<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6970559667014593932</id><updated>2011-11-06T11:53:54.235-05:00</updated><category term='Dojo'/><category term='snippets'/><category term='icymi'/><category term='tools'/><category term='cygwin'/><category term='methodology'/><category term='XML'/><category term='EFR'/><category term='school'/><category term='VB'/><category term='links'/><category term='_meta_'/><category term='work-life balance'/><category term='C++'/><category term='PHP'/><category term='clone'/><category term='Conferences'/><category term='CSS3'/><category term='Zelda'/><category term='MUGEN'/><category term='tinyblog'/><category term='JavaScript'/><category term='HTML5'/><category term='GeoWeb'/><category term='Silverlight'/><title type='text'>Palagpat Coding</title><subtitle type='html'>Fun with JavaScript, game theory, and the occasional outbreak of seriousness</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>66</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7407952860509066266</id><published>2010-09-27T22:50:00.000-05:00</published><updated>2010-09-27T22:50:58.163-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='tinyblog'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><title type='text'>Reclaiming Content: A Manifesto</title><content type='html'>&lt;p&gt;I've been thinking for a while now about trying to get away from using a hosted blog, but I wasn't satisfied with WordPress &amp;mdash; I found it too complicated to do what I really wanted with it, plus it opened me up to all kinds of comment spam and malicious attacks of other sorts. Yes, I realize that I could keep it patched up and minimize my attack profile, but it would still be there. That's the hazard of using something that's widespread: it makes an attractive target.&lt;/p&gt;

&lt;p&gt;Beyond that, I'd also like to archive the URLs to things I share online, e.g. on &lt;a href="http://twitter.com/buyog"&gt;Twitter&lt;/a&gt;. There are services that help with this sort of thing: &lt;a href="http://del.icio.us"&gt;del.icio.us&lt;/a&gt;, &lt;a href="http://bit.ly"&gt;bit.ly&lt;/a&gt;, etc etc etc. But anytime I'm giving my data to someone else, I'm a little uneasy, for a couple of reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What are they going to do with that information? Google and Facebook have both gotten really good at targeting ads at me, and I don't like it.&lt;/li&gt;
&lt;li&gt;What happens if their servers suddenly dump my data, like Twitter &lt;a href="http://twitter.com/buyog/status/22018245305"&gt;recently did&lt;/a&gt; to my @-replies, or like Google Buzz &lt;a href="http://leoville.com/buzz-kill"&gt;did&lt;/a&gt; a few weeks ago to Leo Laporte?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, here's what I'm going to do about it.&lt;/p&gt;

&lt;h2&gt;Manifesto of the Independent Voice&lt;/h2&gt;
&lt;p&gt;I reject the notion that &lt;q&gt;free&lt;/q&gt; on the Internet can only be achieved through selling one's soul to corporate interests. I declare that search engines and blog services &lt;em&gt;do not&lt;/em&gt; own the rights to my voice and my words; &lt;em&gt;I&lt;/em&gt; do!&lt;/p&gt;

&lt;p&gt;I hereby declare my intention to divorce myself from all third-party content management systems. If I cannot &lt;em&gt;find&lt;/em&gt; a suitable open-source blogging platform or content management system, I will build my own.&lt;/p&gt;

&lt;p&gt;Small.&lt;/p&gt;
&lt;p&gt;Fast.&lt;/p&gt;
&lt;p&gt;Simple.&lt;/p&gt;
&lt;p&gt;Free and Independent.&lt;/p&gt;
&lt;p&gt;Mine.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7407952860509066266?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7407952860509066266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/reclaiming-content-manifesto.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7407952860509066266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7407952860509066266'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/reclaiming-content-manifesto.html' title='Reclaiming Content: A Manifesto'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2464099228094174286</id><published>2010-09-27T04:35:00.009-05:00</published><updated>2010-09-28T23:05:07.195-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><title type='text'>In Case You Missed It: JSConf.eu 2010 (day 2)</title><content type='html'>&lt;p&gt;As expected, &lt;a href="http://palagpat-coding.blogspot.com/2010/09/in-case-you-missed-it-jsconfeu-2010-day.html"&gt;Day 1&lt;/a&gt; of this weekend's JSConf.eu JavaScript conference in Berlin was, as the kids say, EPIC. So much so, in fact, that I found myself following the &lt;a href="http://twitter.com/#search?q=%23jsconf"&gt;Twitter channel&lt;/a&gt; all morning, and retweeting WAY more often than usual. Of course, a lot of those retweets were to presenter-uploaded slide decks, but here they all are in one place, &lt;a href="http://palagpat-coding.blogspot.com/search/label/icymi"&gt;in case you missed it&lt;/a&gt;:&lt;/p&gt;

&lt;table width="100%"&gt;
&lt;thead&gt;&lt;th&gt;Speaker(s)&lt;/th&gt;&lt;th&gt;Topic&lt;/th&gt;&lt;/thead&gt;
&lt;tbody&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;THEATRE (TRACK A)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Loopage&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jensarps"&gt;Jens Arps&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/jensarps/the-hitchhikers-guide-to-client-side-persistent-storage"&gt;The hitchhiker's guide to client side persistent data storage&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/ryah"&gt;Ryan Dahl&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://nodejs.org/jsconf-eu-2010.pdf"&gt;Techniques for a single stack world&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jedschmidt"&gt;Jed Schmidt&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/tr4nslator/sets/72157624919090221"&gt;Getting functional with (fab)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/sh1mmer"&gt;Tom Hughes-Croucher&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/sh1mmer/jsconf-eu2010"&gt;Don't write spaghetti code in server side JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/dangoor"&gt;Kevin Dangoor&lt;/a&gt;, &lt;a href="http://twitter.com/joewalker"&gt;Joe Walker&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/pcwalton"&gt;Patrick Walton&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;s&gt;Bespin&lt;/s&gt;Skywriter: The JavaScript Programmer's Editor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/bassistance"&gt;Jörn Zaefferer&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/nonken"&gt;Nikolai Onken&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/dATFpL"&gt;Robotic JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/novemberborn"&gt;Mark Wubben&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://11born.net/jsconfeu/slides"&gt;Browser Extensions for Web Hackers&lt;/a&gt; (&lt;a href="http://11born.net/jsconfeu/code"&gt;code&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/langalex"&gt;Alexander Lang&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://bit.ly/cwNgem"&gt;Not your unit test&lt;/a&gt; (note: Chrome on OS X)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/stoyanstefanov"&gt;Stoyan Stefanov&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/stoyan/performance-patterns"&gt;Performance Patterns&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/voodootikigod"&gt;Chris Williams&lt;/a&gt; (JSConf co-creator)&lt;/td&gt;&lt;td&gt;Community.js&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;hr/&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;MUSIC SCHOOL (TRACK B)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/paul_irish"&gt;Paul Irish&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://jsconfeu2010-pi.appspot.com/#slide1"&gt;The State of HTML5 : Inaugural Address&lt;/a&gt; (note: Webkit/Chrome required) (sidebar on &lt;a href="http://j.mp/ddAlLB"&gt;polyfills&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/tobeytailor"&gt;Tobias Schneider&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/a5BZt6"&gt;Not your Mother's JavaScript!&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/wpbasti"&gt;Sebastian Werner&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/wpbasti/unify-jsconfeu-2010"&gt;Introducing Unify - A Framework for Cross Platform Applications&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/rauchg"&gt;Guillermo Rauch&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://cl.ly/2XzX"&gt;Socket.IO: Web Sockets for Everyone&lt;/a&gt; (&lt;a href="http://github.com/learnboost/nodestream"&gt;nodestream&lt;/a&gt;, &lt;a href="http://github.com/guille/jsconf-todo-demo"&gt;demo&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/tomayac"&gt;Thomas Steiner&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="https://chrome.google.com/extensions/detail/iceopjodmdipccjbknbjolkfogkgloei"&gt;Pirating the Semantic Web with JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/asual"&gt;Rotislav Hristov&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The Art of deep linking and AJAX crawling&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/kriskowal"&gt;Kris Kowal&lt;/a&gt;&lt;/td&gt;&lt;td&gt;CommonJS, I Promise&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/aq"&gt;Aaron Quint&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://swinger.quirkey.com/#/preso/sammy-jsconfeu/display/1"&gt;The Front-end Takeover&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jdalton"&gt;John David Dalton&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Srsly R1pp3d J@vaScript&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/embedjs"&gt;embedJS team&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/cxAv8S"&gt;What is embedJS&lt;/a&gt; (I don't see this one on the schedule, only in the Twitter stream; where was it?)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Undoubtedly there will be more slide decks uploaded as presenters return home over the next day or two, and when they do, I'll update this post to reflect those additions. For now, though, I've got plenty of reading material to digest, and to share with my co-workers. ;)&lt;/p&gt;

&lt;p&gt;Projects released and/or updated this weekend (as compiled by &lt;a href="http://twitter.com/brianleroux/status/25601434722"&gt;Brian Leroux&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://cloud9ide.com"&gt;Cloud9 IDE&lt;/a&gt; (by Javascripters, for Javascripters)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://unify-project.org"&gt;Unify&lt;/a&gt;: single-stack project for developing cross-platform, native-looking mobile apps&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scripty2.com"&gt;Scripty2 beta 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://apparat.io"&gt;apparat.io&lt;/a&gt;: packaging HTML5 apps for mobile app stores&lt;/li&gt;
&lt;li&gt;&lt;a href="http://build.phonegap.com"&gt;PhoneGap's hosted build service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://no.de"&gt;Joyent's node.js hosting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="vaporjs.com"&gt;VaporJS&lt;/a&gt;: the smallest, fastest, &lt;span style="font-size:smallest"&gt;(most useless)&lt;/span&gt; JavaScript framework ever!&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/quirkey/soca"&gt;soca&lt;/a&gt;: Sammy on Couch App&lt;/li&gt;
&lt;a href="http://github.com/learnboost/nodestream"&gt;nodestream&lt;/a&gt;: Realtime apps made easy with templating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet another great conference has come and gone, but now we can start looking forward to JSConf 2011. And next time, I'm going to do all in my power to give my recap &lt;em&gt;first-hand&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updates&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;9/27 0747 - Added link to Jed Schmidt's slides&lt;/li&gt;
&lt;li&gt;9/27 1403 - Added link to Sebastian Werner's slides&lt;/li&gt;
&lt;li&gt;9/27 1732 - Added link to Tom Hughes-Crouche's slides&lt;/li&gt;
&lt;li&gt;9/28 1108 - Added link to Jens Arps' slides&lt;/li&gt;
&lt;li&gt;9/28 1442 - Added link to Alexander Lang's slides (note that they require Chrome on OS X for best experience)&lt;/li&gt;
&lt;li&gt;9/28 2330 - Added link to Tobias Schneider's slides&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2464099228094174286?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2464099228094174286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/in-case-you-missed-it-jsconfeu-2010-day_27.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2464099228094174286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2464099228094174286'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/in-case-you-missed-it-jsconfeu-2010-day_27.html' title='In Case You Missed It: JSConf.eu 2010 (day 2)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2676405493348797850</id><published>2010-09-25T14:44:00.011-05:00</published><updated>2010-09-28T10:19:59.963-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><title type='text'>In Case You Missed It: JSConf.eu 2010 (day 1)</title><content type='html'>&lt;p&gt;This weekend, the second annual &lt;a href="http://jsconf.eu/2010/"&gt;JSConf.eu&lt;/a&gt; conference was held in Berlin, Germany. If you've been keeping track, this JSConf juggernaut just keeps getting bigger and more epic with each successive iteration. Continuing my series, &lt;a href="http://palagpat-coding.blogspot.com/search/label/icymi"&gt;In Case You Missed It&lt;/a&gt;, let's take a peek at this weekend's &lt;a href="http://jsconf.eu/2010/schedule-2010.html"&gt;published schedule&lt;/a&gt; and the accompanying &lt;a href="http://twitter.com/#search?q=%23jsconf"&gt;Twitter stream&lt;/a&gt; to see if the trend continues.&lt;/p&gt;

&lt;h5&gt;Day 1: Saturday, September 25, 2010&lt;/h5&gt;

&lt;table width="100%"&gt;
&lt;thead&gt;&lt;th&gt;Speaker(s)&lt;/th&gt;&lt;th&gt;Topic&lt;/th&gt;&lt;/thead&gt;
&lt;tbody&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;THEATRE (TRACK A)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/dalmaer"&gt;Dion Almaer&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/bgalbs"&gt;Ben Galbraith&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Using the Web to deliver the next wave of computing experiences&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/phiggins"&gt;Peter Higgins&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/aU5HAI"&gt;Your library sucks, and why you should use it&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/JennLukas"&gt;Jenn Lukas&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/JennLukas/javascript-and-web-standards-2-the-quickening"&gt;JavaScript + Web Standards II: The Quickening&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/creationix"&gt;Tim Caswell&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/bA42Ff"&gt;Techniques and Tools for Taming Tangled Twisted Trains of Thought&lt;/a&gt; (&lt;a href="http://creationix.com/jsconf.pdf"&gt;PDF&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ulrike Müller&lt;/td&gt;&lt;td&gt;Server-side JavaScript the untold story&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/stubbornella"&gt;Nicole Sullivan&lt;/a&gt;&lt;/td&gt;&lt;td&gt;CSS Lint for Massive Sites&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brianleroux"&gt;Brian LeRoux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="https://docs.google.com/present/view?id=d99cqmc_389hntm6hcp"&gt;PhoneGap: Love the Web and Lose the SDK&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/bfirsh"&gt;Ben Firshman&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://jsconfeu2010-bfirsh.heroku.com/"&gt;Lessons learnt pushing browsers to the limit&lt;/a&gt; (links: &lt;a href="http://bit.ly/cwF4D5"&gt;1&lt;/a&gt; &lt;a href="http://mzl.la/clKzIg"&gt;2&lt;/a&gt; &lt;a href="http://bit.ly/bXiPcG"&gt;3&lt;/a&gt; &lt;a href="http://bit.ly/blptjz"&gt;4&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/mutle"&gt;Mutwin Kraus&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://github.com/mutle/jsconf_games"&gt;Using canvas to develop classic 2D games&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/rmurphey"&gt;Rebecca Murphy&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/9ySoiG"&gt;The jQuery Divide&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/petele"&gt;Pete LePage&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Chakra: Building A New JavaScript Engine For Internet Explorer 9&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brendaneich"&gt;/be (Brendan Eich)&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/bgSHNJ"&gt;Proxies are Awesome!&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;hr/&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;MUSIC SCHOOL (TRACK B)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/robertnyman"&gt;Robert Nyman&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/dmEPLy"&gt;HTML5 APIs - The new Frontier&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/philogb"&gt;Nicolas Garcia Belmonte&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/97GONM"&gt;Creating Interactive Data Visualizations for the Web&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/sippndipp"&gt;Sebastian Deutsch&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/evilhackerdude"&gt;Stephan Seidt&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.scribd.com/doc/38122875/If-It-Moves-They-Will-Watch-It"&gt;If it moves they will watch&lt;/a&gt; (&lt;a href="http://9elements.com/io/?p=492"&gt;sample code&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/pbakaus"&gt;Paul Bakaus&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Aves Engine: High performance browser games&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/mikeal"&gt;Mikeal Rogers&lt;/a&gt;&lt;/td&gt;&lt;td&gt;node.js + CouchDB == Crazy Delicious&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/felixge"&gt;Felix Geisendörfer&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/the_undefined/dir-5299121"&gt;Dirty NoSQL&lt;/a&gt; (&lt;a href="http://github.com/felixge/node-dirty"&gt;code&lt;/a&gt;, &lt;a href="http://debuggable.com/posts/jsconf-roundup:4ca0de2f-e30c-4c03-87bb-2bd7cbdd56cb"&gt;blog&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/pilif"&gt;Philip Hofstetter&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.pilif.ch/ta-presentation/"&gt;node.js in production use: tempalias.com&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Markus Franz&lt;/td&gt;&lt;td&gt;Better Life with shared resources&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/joemccann"&gt;Joe McCann&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/chGncz"&gt;Rapid Prototyping for Multiple Platforms with JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/fjakobs"&gt;Fabian Jakobs&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://slidesha.re/a7AcK4"&gt;Kick ass code editing and end-to-end Javascript debugging&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Some of my favorite finds/revelations of the day:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://github.com/pbakaus/transformie"&gt;Transformie&lt;/a&gt;: provides CSS Transforms for Internet Explorer by mapping the native IE filter API&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.insidesocialgames.com/2010/09/24/zynga-acquires-dextrose-aves-engine-html5/"&gt;Zynga buys out HTML5-based Aves game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://transloadit.com/"&gt;Transloadit&lt;/a&gt;: cool new service to provide robust file uploading (with image resizes, video encoding, etc)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/madrobby/vapor.js"&gt;vapor.js&lt;/a&gt;, the smallest, fastest JavaScript library &lt;em&gt;ever&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cloud9ide.com/"&gt;Cloud9 IDE&lt;/a&gt;: the Javascript IDE by Javascripters, for Javascripters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look for tomorrow's recap late in the afternoon, and as always, if there are slide decks from other talks online that I don't have linked here, please note it in the comments below, and I'll update accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updates&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;9/26 0530 - Added link to Rebecca Murphey's slide deck&lt;/li&gt;
&lt;li&gt;9/26 1813 - Added links to Jenn Lukas &amp;amp; Fabian Jakobs' slide decks, and removed speakers whose sessions were cancelled.&lt;/li&gt;
&lt;li&gt;9/26 1839 - Added link to Philip Hofstetter's slide deck&lt;/li&gt;
&lt;li&gt;9/26 1847 - Added link to Mutwin Kraus's github repository (which includes the slides)&lt;/li&gt;
&lt;li&gt;9/28 0549 - Added link to Brendan Eich's slides&lt;/li&gt;
&lt;li&gt;9/28 1119 - Added link to Felix Geisendörfer's slides &amp;amp; recap&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2676405493348797850?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2676405493348797850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/in-case-you-missed-it-jsconfeu-2010-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2676405493348797850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2676405493348797850'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/in-case-you-missed-it-jsconfeu-2010-day.html' title='In Case You Missed It: JSConf.eu 2010 (day 1)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7104702593481867413</id><published>2010-09-16T08:22:00.000-05:00</published><updated>2010-09-16T08:22:13.432-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>IE9: Microsoft Strikes Back</title><content type='html'>&lt;p&gt;After pretty much ignoring Internet Explorer for the last few years, I'm surprised to find myself using the &lt;a href="http://www.beautyoftheweb.com/"&gt;latest and greatest version&lt;/a&gt; this morning. And so far? I like it.&lt;/p&gt;

&lt;p&gt;The first thing I did once I got the new browser beta up and running was to check out my own site, where I've got a pretty good idea of what previously didn't work well (or at all) in IE. What I found surprised me:&lt;/p&gt;

&lt;a name="good"&gt;&lt;h3&gt;What Works&lt;/h3&gt;&lt;/a&gt;
&lt;ul&gt;
 &lt;li&gt;Surprisingly, &lt;a href="http://buyog.com/code/loc/Canvassa/"&gt;Canvassa&lt;/a&gt;! IE9 runs my little HTML5 Canvas game quite well, in fact.&lt;/li&gt;
 &lt;li&gt;My &lt;a href="http://buyog.com/code/resume.php"&gt;resume&lt;/a&gt; looks great. The only advanced feature it doesn't do right is &lt;a href="http://palagpat-coding.blogspot.com/2010/08/one-page-resume-in-css3.html#liquid"&gt;liquid columns&lt;/a&gt;, but that's relatively minor, really.&lt;/li&gt;
&lt;/ul&gt;

&lt;a name="bad"&gt;&lt;h3&gt;What Doesn't Work&lt;/h3&gt;&lt;/a&gt;
&lt;ul&gt;
 &lt;li&gt;My &lt;a href="http://buyog.com/code/folio.php"&gt;portfolio&lt;/a&gt; doesn't work. Time to revisit some of that code.&lt;/li&gt;
 &lt;li&gt;The new "&lt;a href="http://www.beautyoftheweb.com/?fbid=NOFBID&amp;mtag=mbar-twitter#/highlights/seamless-with-windows-7"&gt;pinning a webpage as an app&lt;/a&gt;" functionality doesn't look very good for my site yet; I need to figure out what &amp;lt;meta&amp;gt; tags to include to make it look better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else seems to be working well. The new developer tools are nice, addon-disabling feature was pretty sweet, and the minimal browser chrome gets out of the way on my tiny netbook screen and lets the Web shine through. Overall, I've got to hand it to the IE team: this is a &lt;em&gt;great&lt;/em&gt; step in the right direction, and I for one welcome the return of the Browser Wars... because Competition = Innovation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7104702593481867413?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7104702593481867413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/ie9-microsoft-strikes-back.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7104702593481867413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7104702593481867413'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/09/ie9-microsoft-strikes-back.html' title='IE9: Microsoft Strikes Back'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6867111732675580182</id><published>2010-08-23T11:27:00.003-05:00</published><updated>2010-09-22T09:31:05.057-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Candles, or the Magic of dojo.connect</title><content type='html'>&lt;img src="http://buyog.com/code/images/loc_candle.png" alt="The versatile blue candle" style="float:left; border:1px solid black; width:256px; height: 240px; margin: 0 10px 10px 0"/&gt;
&lt;p&gt;It's been a while since I've worked on &lt;a href="http://palagpat-coding.blogspot.com/search/label/Zelda"&gt;Canvassa&lt;/a&gt;, my HTML5 love letter to the original 8-bit NES Legend of Zelda. If you remember &lt;a href="http://palagpat-coding.blogspot.com/2010/02/cloning-zelda-whither-chrome.html"&gt;last time&lt;/a&gt;, we worked out some kinks in the code that were causing it to crash in Google Chrome. Today, it's back to implementing missing functionality: namely, how to make the blue candle behave appropriately. Fortunately, Dojo provides us a way to do this, and it's actually a pretty cool feature of the framework. Read on to see how it works.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h4&gt;Step 1: Defining the missing behavior&lt;/h4&gt;

&lt;p&gt;In the original game, the blue candle was one of the first items available to you: for the bargain price of 60 rupees, you could buy it from the merchant just around the corner. As such, it had some cool functionality (damaging enemies, burning down trees), but one steep limitation: you could only use it once on any given screen. When I first implemented the candle item, it included no such limitation &amp;mdash; mainly because I didn't want to pollute the main game loop by writing some specialized code for that purpose in the &lt;code&gt;loc.Game&lt;/code&gt; class. Rather, I wanted to keep the game loop as clean as possible, and let all of Link's inventory items take care of themselves as much as possible.&lt;/p&gt;

&lt;h4&gt;Step 2: Framing the Problem&lt;/h4&gt;

&lt;p&gt;I determined that what I needed was a way for the candle to know when Link had moved to a new screen, and reset itself whenever that happened. This suggested the need for either the candle object to poll the player's position on a regular basis, or the player object to notify the candle object when its position changed. Neither solution appealed to me: having the candle object query the player object for anything at all seemed hackish at best (especially since proper encapsulation dictates that an owned object shouldn't be privy to all of its owner's properties), and forcing the player object to notify the candle object whenever it entered a new screen would tightly bind the two objects, requiring one to know and manage the internal state of the other &amp;mdash; something I want to avoid if at all possible.&lt;/p&gt;

&lt;p&gt;The solution lies in an often-overlooked corner of Dojo Base called &lt;code&gt;dojo.connect&lt;/code&gt;, which allows us to create event listeners for not only DOM events, but &lt;em&gt;any&lt;/em&gt; arbitrary JavaScript functions that we want. Here's how &lt;a href="http://docs.dojocampus.org/dojo/connect"&gt;DojoCampus&lt;/a&gt; describes it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre&gt;
// When ob.onCustomEvent executes, customEventHandler is invoked:
dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our case, we want the player inventory to be listening for an event that tells us that the game's map screen has changed. Here's how it works:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
// in Player.js:

updateInventory: function{} {
...
// when Link first picks up the candle:
dojo.connect(game, 'setupMapScreen', this.resetItems);
...
}

resetItems: function() {
    // reset the candle
    game.player.inventory[3].reset();
}

// in Item.js:
dojo.declare("loc.Candle", [loc.Item, loc.InventoryItem], {
...
    available: true,
...
    getProjectile: function(args) {
        // if we're color=0 (blue), check to see if we've been used already on this screen
        if (this.available || this.color) {
            this.available = false;
            soundManager.play('candle');
            return new loc.FlameProj(args);
        }
    },
    reset: function() { this.available = true; }
});
&lt;/pre&gt;

&lt;p&gt;Once you pick up the blue candle, the Player class starts listening for the Game class to run its &lt;code&gt;setupMapScreen&lt;/code&gt; function, &lt;em&gt;which is not an event&lt;/em&gt;. When that function is invoked, Dojo lets Player know, and it quietly resets inventory item #3 (i.e. the loc.Candle object). When the Player has the blue candle equipped, the &lt;code&gt;getProjectile&lt;/code&gt; call, which is used to get the loc.FlameProj projectile-flame object, first checks to see if &lt;code&gt;available&lt;/code&gt; is true, or failing that, if its color is nonzero (the red candle, which comes much later in the game, doesn't have the once-per-screen limitation, and is assigned color=1). Not too tricky, and it allows each object to take care of itself as much as possible.&lt;/p&gt;

&lt;p&gt;The full change set for this feature is in my &lt;a href="http://github.com/buyog/Canvassa/"&gt;Github repository&lt;/a&gt;, which also includes several other tweaks I've made in the past several months but never had the time or inclination to blog about. If you see something you'd like to fix, feel free to fork it and give it a shot.&lt;/p&gt;

&lt;p&gt;I'm starting to see areas where the code needs a refactoring, particularly in regards to the need for multiple game maps (i.e. for dungeons). Next time I'll begin to tackle the necessary changes to make this work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6867111732675580182?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6867111732675580182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/cloning-zelda-candles-or-magic-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6867111732675580182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6867111732675580182'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/cloning-zelda-candles-or-magic-of.html' title='Cloning Zelda: Candles, or the Magic of dojo.connect'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5368556039321038319</id><published>2010-08-10T10:29:00.003-05:00</published><updated>2010-09-16T08:10:35.614-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS3'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><title type='text'>One-page resume in CSS3</title><content type='html'>&lt;style type="text/css"&gt;
.caption {
  font-weight:bold; margin:0; padding:0;
}
&lt;/style&gt;

&lt;p&gt;Recently, I came across a really nicely done &lt;a href="http://www.scribd.com/doc/4633116/A-Very-Cool-One-Page-Resume"&gt;one-page resume&lt;/a&gt; on Scribd, and wanted to try to recreate it using the latest web technologies (no Adobe Acrobat, Microsoft Word, or OpenOffice allowed). Turns out with a few sprinklings of CSS3, it's pretty straightforward. Let's peel back the covers and take a look.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;(If you want to skip straight to the result, you can &lt;a href="http://buyog.com/code/resume.php"&gt;click here&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;Planning&lt;/h3&gt;
&lt;p&gt;First, let's take a look at what features our exemplar uses that we want to try to emulate:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;grid layout (header plus 2-column flow)&lt;/li&gt;
  &lt;li&gt;pseudo-tabular formatting (Experience and Education sections)&lt;/li&gt;
  &lt;li&gt;2-column bulleted list (Software section)&lt;/li&gt;
  &lt;li&gt;custom typeface on headings&lt;/li&gt;
&lt;/ul&gt;

&lt;a name="grid"&gt;&lt;h3&gt;Grid Layout&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;This one was actually pretty easy, and didn't require any sophisticated CSS hackery at all:&lt;/p&gt;
&lt;pre class="brush: css"&gt;
/* set up a simple grid layout */
.resume { width: 860px; margin: 0 auto; }
.leftCol { width: 480px; }
.leftCol, .rightCol { display: inline; float: left; padding-right: 20px; }
/* end grid layout (see? I said it was simple) */
&lt;/pre&gt;

&lt;p&gt;So we just set our &lt;code&gt;.resume&lt;/code&gt; class to a specific width, then use the "&lt;code&gt;margin: 0 auto&lt;/code&gt;" bit to center it horizontally on the page. We fix the width of the left column, set both left and right columns to float, and include 20px of padding to push them slightly apart. Simple, effective, and cross-browser compatible!&lt;/p&gt;

&lt;a name="display-table"&gt;&lt;h3&gt;Tables Without &amp;lt;table&amp;gt;&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;If asked, most modern web developers will tell you that the practice of using &amp;lt;table&amp;gt; tags to do page layout belongs back in the "dark ages" of the Internet, but there are some things that are really hard to do without it. Knowing this, the &lt;abbr title="World-Wide Web Consortium"&gt;W3C&lt;/abbr&gt; gave us a really nice solution... the &lt;a href="http://www.w3.org/TR/CSS2/tables.html#table-display"&gt;CSS Table Model&lt;/a&gt;. In a nutshell, it gives you three new values for the CSS &lt;code&gt;display&lt;/code&gt; property: &lt;code&gt;table&lt;/code&gt;, &lt;code&gt;table-row&lt;/code&gt;, and &lt;code&gt;table-cell&lt;/code&gt;. Used together, they can turn hackish markup like this:&lt;/p&gt;

&lt;pre class="brush: html"&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr valign="top"&gt;
  &lt;td&gt;2008&amp;mdash;present&lt;/td&gt;
  &lt;td&gt;
    &lt;strong&gt;Senior Computer Scientist&lt;/strong&gt;&lt;br/&gt;
    &lt;em&gt;White Oak Technologies, Inc., Silver Spring MD&lt;/em&gt;
  &lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/pre&gt;

&lt;p&gt;... into this, slightly-more-verbose-but-less-hackish markup:&lt;/p&gt;

&lt;pre class="brush: html"&gt;
&lt;div style="display:table-row"&gt;
  &lt;span style="display:table-cell"&gt;2008&amp;mdash;present&lt;/span&gt;
  &lt;span style="display:table-cell"&gt;
    &lt;strong&gt;Senior Computer Scientist&lt;/strong&gt;&lt;br/&gt;
    &lt;em&gt;White Oak Technologies, Inc., Silver Spring MD&lt;/em&gt;
  &lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;

&lt;p&gt;Even better, we can employ some CSS class names and get basic semantics:&lt;/p&gt;
&lt;pre class="brush: css"&gt;
/* new table-display style: works in pretty much all modern browsers except IE before v8 */
.expJob, { display: table-row; }
.expDate, .expDetail { display: table-cell; }
.expDate { width: 7em; }
.jobTitle { font-weight: bold; display: block; }
.jobLoc { font-style: italic; }
&lt;/pre&gt;
&lt;pre class="brush: html"&gt;
&lt;div class="expJob"&gt;
  &lt;span class="expDate"&gt;2008&amp;mdash;present&lt;/span&gt;
  &lt;span class="expDetail"&gt;
    &lt;span class="jobTitle"&gt;Senior Computer Scientist&lt;/span&gt;
    &lt;span class="jobLoc"&gt;White Oak Technologies, Inc., Silver Spring MD&lt;/span&gt;
  &lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;

&lt;p&gt;So is this a &lt;em&gt;bleeding-edge&lt;/em&gt;, CSS3 feature? Not actually, no. It's from CSS 2, and since Internet Explorer 8 was released, it's been supported in &lt;a href="http://caniuse.com/#cats=CSS2"&gt;all current-generation browsers&lt;/a&gt;. As is often the case with these types of things, only IE6 &amp;amp; 7 are the spoilsports. The thing is, though? &lt;a href="http://shouldwebsiteslookthesameinallbrowsers.com/"&gt;I'm not inclined to care that much&lt;/a&gt; if my site looks a little different in some older versions of IE. The default, unstyled behavior isn't bad, it's still readable, just not quite as visually appealing:&lt;/p&gt;

&lt;p class='caption'&gt;Old and Busted:&lt;/p&gt;
&lt;img src="http://buyog.com/code/images/blog_resume_exp0.png"/&gt;

&lt;p class='caption'&gt;New Hotness:&lt;/p&gt;
&lt;img src="http://buyog.com/code/images/blog_resume_exp1.png"/&gt;

&lt;p&gt;This is an example of &lt;a href="http://www.smashingmagazine.com/2009/08/04/designing-a-html-5-layout-from-scratch/"&gt;Graceful Degradation&lt;/a&gt; (albeit not a very impressive one), which is a pretty good idea to use when designing sites with features that aren't ubiquitous across all browsers.&lt;/p&gt;

&lt;a name="liquid"&gt;&lt;h3&gt;Liquid Columns&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;So after those last two, not-all-that-new CSS techniques, here's something that &lt;em&gt;is&lt;/em&gt; a new CSS3 feature. So-called "liquid" layout basically just means that you write the content (say, a magazine article), then make it flow into the layout you want to give it later on. Historically this has been somewhat problematic in the Web world, but that's changing. One of the agents of that change comes in the form of the new &lt;a href="http://www.w3.org/TR/css3-multicol/"&gt;CSS Multi-column Layout Module&lt;/a&gt;. In this instance, we want the bulletted list under the "Software" heading to flow across two columns, making better use of the space available in the resume's right column. This can be easily accomplished with two CSS properties, &lt;code&gt;column-count&lt;/code&gt; and &lt;code&gt;column-gap&lt;/code&gt; (currently, these are only in the latest releases of Firefox and Webkit-enabled browsers like Chrome and Safari, so we'll include the vendor-prefixed versions):&lt;/p&gt;

&lt;pre class="brush: css"&gt;
/* new super-cool CSS3 multi-column layout;
  only in Mozilla/Webkit for now,
  but it degrades to a regular list just fine */
ul.software {
  column-count: 2; column-gap: 2em;
  -moz-column-count: 2; -moz-column-gap: 2em;
  -webkit-column-count: 2; -webkit-column-gap: 2em;
}
&lt;/pre&gt;
&lt;pre class="brush: html"&gt;
&lt;ul class="software"&gt;
  &lt;li&gt;software&lt;/li&gt;
  &lt;li&gt;packages&lt;/li&gt;
  &lt;li&gt;I&lt;/li&gt;
  &lt;li&gt;grok&lt;/li&gt;
&lt;/ul&gt;
&lt;/pre&gt;

&lt;p&gt;Most browsers will render this as:&lt;/p&gt;

&lt;p class='caption'&gt;Non-liquid (single column):&lt;/p&gt;
&lt;img src="http://buyog.com/code/images/blog_resume_list1.png"/&gt;

&lt;p&gt;Current versions of Firefox and Webkit, which both support multi-column layout, will instead do this:&lt;/p&gt;

&lt;p class='caption'&gt;Liquid! (two columns):&lt;/p&gt;
&lt;img src="http://buyog.com/code/images/blog_resume_list0.png"/&gt;

&lt;p&gt;This is another case where the default behavior looks fine, and the new CSS features just make it a little bit nicer. The cool kids call this &lt;a title="need a link here"&gt;Progressive Enhancement&lt;/a&gt;, which is really just Graceful Degradation seen from the other side of the river. The only difference in these two techniques is whether you design the enhanced behavior first and then patch the fallback rendering (graceful degradation), or design the default case first and then enhance it where possible (progressive enhancement).&lt;/p&gt;

&lt;a name="font-face"&gt;&lt;h3&gt;Fancy Font&lt;/h3&gt;&lt;/a&gt;

&lt;p&gt;Finally, let's take a look at our typefaces. In an inversion of their common perception as Johnny-come-latelies, &lt;a href="http://reference.sitepoint.com/css/at-fontface"&gt;Internet Explorer&lt;/a&gt; has had the ability to include custom fonts in a web page for quite a few versions. This is a feature that the other browsers haven't fully embraced until fairly recently, and even now, every browser's implementation of the &lt;code&gt;font-face&lt;/code&gt; at-rule is &lt;em&gt;just different enough&lt;/em&gt; to cause anyone headaches. There's been quite a bit of traction in the past year, though, and I recently discovered a great site that has taken the collective findings of great web font pioneers like &lt;a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/"&gt;Paul Irish&lt;/a&gt; and others to make custom web fontography &lt;em&gt;almost&lt;/em&gt; (not quite, but almost) a no-brainer: &lt;a href="http://www.fontsquirrel.com"&gt;fontsquirrel.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Browsing FontSquirrel's list of &lt;a href="http://www.fontsquirrel.com/fontface"&gt;available free font kits&lt;/a&gt;, I found &lt;a href="http://www.fontsquirrel.com/fonts/ChunkFive"&gt;ChunkFive&lt;/a&gt;, which looks like a pretty good match for the font in the resume we're trying to match. FontSquirrel provides hundreds of @font-face kits for free download, so we just grab the &lt;a href="http://www.fontsquirrel.com/fontfacedemo/ChunkFive"&gt;kit for ChunkFive&lt;/a&gt;, extract it to a folder on our web server, and link to it with a single line in our header:&lt;/p&gt;

&lt;pre class="brush: html"&gt;
&lt;!-- grab custom font-face, courtesy fontsquirrel.com (yay!) --&gt;
&amp;lt;link rel="stylesheet" href="/fonts/chunkfive/stylesheet.css" type="text/css" charset="utf-8"/&amp;gt;
&lt;/pre&gt;

&lt;p&gt;With the cross-browser details abstracted away for us by this stylesheet, all it takes to use the new font is an ordinary CSS font property:&lt;/p&gt;

&lt;pre class="brush: css"&gt;
.header h1 { font: 32pt/24pt 'ChunkFiveRegular', Arial, sans-serif; }
h2 { font: 1.7em/1em 'ChunkFiveRegular', Arial, sans-serif; }
h3 { font: 1.2em/1em 'ChunkFiveRegular', Arial, sans-serif; }
&lt;/pre&gt;

&lt;p&gt;For any browser that doesn't support @font-face yet (notably including &lt;a href="http://sixrevisions.com/css/font-face-guide/"&gt;most mobile browsers&lt;/a&gt;), the ChunkFive font kit suggests providing fallbacks to Arial and sans-serif, so we do just that. Just like that, we take the look of our resume from &lt;em&gt;blah&lt;/em&gt;:&lt;/p&gt;

&lt;img src="http://buyog.com/code/images/blog_resume_font0.png" style="border:1px solid black;"/&gt;

&lt;p class='caption'&gt;... to &lt;em&gt;Bam&lt;/em&gt;:&lt;/p&gt;
&lt;img src="http://buyog.com/code/images/blog_resume_font1.png" style="border:1px solid black;"/&gt;

&lt;h3&gt;Et Voila!&lt;/h3&gt;

&lt;p&gt;Having done all of the above, &lt;a href="http://buyog.com/code/resume.php"&gt;here's&lt;/a&gt; my final product. (If you don't have a browser that supports off of these features, you can see a PDF version &lt;a href="http://buyog.com/code/resume.pdf"&gt;here&lt;/a&gt;). If I had more time and creativity, I would have made a phony resume for &lt;a href="http://en.wikipedia.org/wiki/Spider-Man"&gt;Peter Parker&lt;/a&gt; instead, but you get the idea.&lt;/p&gt;

&lt;p&gt;Once I'd gotten this far, I realized several things that would make it even better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It would've been pretty cool (although ultimately kind of pointless) to create the header logo on the fly in Canvas&lt;/li&gt;
&lt;li&gt;This format doesn't include the number of years of experience on skills / technologies / software&lt;/li&gt;
&lt;li&gt;It also doesn't have "accomplishment" bullets on experience / education sections.&lt;/li&gt;
&lt;li&gt;There should be a way to get a &lt;em&gt;full&lt;/em&gt; list of jobs instead of just the few selected ones I chose here.&lt;/li&gt;
&lt;li&gt;Maybe add a Publications section (including this blog, of course)...?&lt;/li&gt;
&lt;li&gt;Use more semantic markup, in particular &lt;a href="http://www.ablognotlimited.com/articles/getting-semantic-with-microformats-part-6-hresume/"&gt;Microformats&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Microformats will give your data some computer-processable meaning, which sites like Google are &lt;a href="http://microformats.org/wiki/google-search"&gt;starting to use&lt;/a&gt; to good effect. But we'll save that for another day. The rest of these quibbles are just stylistic choices, really. A one-page resume isn't designed to carry every single piece of information a potential employer or client needs to make a decision, it's to grab their attention. I think this does that job pretty well.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5368556039321038319?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5368556039321038319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/one-page-resume-in-css3.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5368556039321038319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5368556039321038319'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/one-page-resume-in-css3.html' title='One-page resume in CSS3'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8694344015685562234</id><published>2010-08-04T23:42:00.003-05:00</published><updated>2010-08-04T23:54:37.338-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Slaying the Beast</title><content type='html'>&lt;p&gt;So tell me if this &lt;a href="http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5b-non-stupid-ais.html"&gt;sounds&lt;/a&gt; &lt;a href="http://pugadngbuyog.blogspot.com/2010/01/resolutions.html"&gt;familiar&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;strong&gt;goal&lt;/strong&gt;: build up my online portfolio.&lt;br/&gt;
&lt;em&gt;how I'll do it&lt;/em&gt;: maintain a regular blogging schedule (this, too, I'll write more about soon)
&lt;/blockquote&gt;

&lt;p&gt;Yeah, not so much. Instead, the past 6 months of my life have been swallowed up by a ravenous beast known as "graduate school," that has grown more and more aggressive in the past 3 or 4 weeks. I dealt it a mortal blow when I passed my defense on Monday the 19th, but it limped along for a while, whispering to me of Target Audiences, Proper Whitespacing, and Nested Bookmarks. Today, I think it finally gasped its last breath, but I have to wait until tomorrow for the official word from the &lt;s&gt;graduate reviewer&lt;/s&gt;coroner.&lt;/p&gt;

&lt;p&gt;So, this is me saying "I'm back." I have a half-dozen half-finished posts in draft, way more free time than I'm used to, and a lot to catch up on.&lt;/p&gt;

&lt;p&gt;See you soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8694344015685562234?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8694344015685562234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/slaying-beast.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8694344015685562234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8694344015685562234'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/08/slaying-beast.html' title='Slaying the Beast'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1284252928092173254</id><published>2010-06-09T07:28:00.037-05:00</published><updated>2010-09-16T13:42:42.120-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><title type='text'>In Case You Missed It: TXJS</title><content type='html'>&lt;p&gt;Last Saturday was the inaugural &lt;a href="http://texasjavascript.com/"&gt;TXJS&lt;/a&gt; (Texas JavaScript) conference in Austin, Texas. Unfortunately, as with &lt;a href="http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html"&gt;JSConf&lt;/a&gt;, I wasn't able to attend, but I still wanted to stay abreast of its happenings. Just as I did with JSConf, I've looked over the schedule, picked through the &lt;a href="http://twitter.com/#search?q=%23txjs"&gt;Twitter&lt;/a&gt; stream, followed &lt;a href="http://twitter.com/#/list/buyog/txjs" title="all TXJS presenters on Twitter"&gt;the presenters&lt;/a&gt;, and where possible, found links to the slides they each presented. All for &lt;em&gt;you&lt;/em&gt;, Dear Readers (well, for me too... but mostly for you ;) ).&lt;/p&gt;

&lt;p&gt;So anyway, without further adieu, here we go!&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3&gt;In Case You Missed It: TXJS&lt;/h3&gt;
&lt;h4&gt;Saturday, June 5, 2010&lt;/h4&gt;

&lt;table width="100%"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Speaker(s)&lt;/th&gt;&lt;th&gt;Topic&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK A&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/douglascrockford/newandimproved"&gt;
ECMAScript 5: the New &amp;amp; Improved Parts&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jeresig"&gt;John Resig&lt;/a&gt;&lt;/td&gt;&lt;td&gt;JavaScript on the Mobile Web&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/danwrong"&gt;Dan Webb&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/danwrong/building-anywhere-for-txjs"&gt;Building @anywhere: A Client-side Interface to Twitter&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/paul_irish"&gt;Paul Irish&lt;/a&gt;&lt;/td&gt;&lt;td&gt;10 Things I Learned from the jQuery Source&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/stubbornella"&gt;Nicole Sullivan&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The Top 5 Mistakes of Massive CSS&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/sh1mmer"&gt;Tom Hughes-Croucher&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/sh1mmer/txjs-4424188"&gt;JavaScript Everywhere! Creating a 100% JavaScript web stack&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/kangax"&gt;Juriy Zaytsev&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Dive into ECMAScript 5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/phiggins"&gt;Peter Higgins&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/phiggins/txjs"&gt;It's Just JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brianleroux"&gt;Brian LeRoux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/brianleroux/txjs"&gt;F#$% Yeah, Mobile JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK B&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/tomocchino"&gt;Tom Occhino&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Front End Abstractions at Facebook&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/miketaylr"&gt;Mike Taylor&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://miketaylr.com/pres/txjs/MikeTaylor_txjs_2010.pdf"&gt;Regressive Enhancement, or HTML5 for crappy browsers&lt;/a&gt; (PDF)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/joemccann"&gt;Joe McCann&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Rapid Prototyping with JavaScript&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/uhop"&gt;Eugene Lazutkin&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/elazutkin/dojo-for-programmers"&gt;Dojo for Programmers&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/SlexAxton"&gt;Alex Sexton&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://speakerrate.com/talks/3316-breaking-the-cross-domain-barrier"&gt;Breaking The Cross Domain Barrier&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/andrewdupont"&gt;Andrew Dupont&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/savetheclocktower/how-custom-events-will-save-the-universe"&gt;How Custom Events Will Save The Universe&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brandonaaron"&gt;Brandon Aaron&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/brandon.aaron/special-events-beyond-custom-events"&gt;Special Events: Beyond Custom Events&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/creationix"&gt;Tim Caswell&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/creationix/real-time-web-with-node"&gt;Writing a real-time game with NodeJS&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/getify"&gt;Kyle Simpson&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/shadedecho/ui-architecture-web-performance"&gt;Web Performance &amp;amp; UI Architecture&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK C&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/douglascrockford/jsonsag"&gt;The JSON Saga&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jvgogh"&gt;Jeffrey Van Gogh&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Reactive Extensions for JavaScript&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/unscriptable"&gt;John Hann&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/unscriptable/cujo-dojo-css3-mvc"&gt;Sneak Peek: Cujo - Dojo, CSS3, MVC&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/hugs"&gt;Jason Huggins&lt;/a&gt;&lt;/td&gt;&lt;td&gt;JavaScript Frameworks &amp;amp; Functional Testing (panel, no slides)&lt;/td&gt;&lt;/tr&gt;

&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;As of now, this is what I could find. If there are slide decks from other talks online that I don't have linked here, please note it in the comments below, and I'll update accordingly.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1284252928092173254?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1284252928092173254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/06/in-case-you-missed-it-txjs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1284252928092173254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1284252928092173254'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/06/in-case-you-missed-it-txjs.html' title='In Case You Missed It: TXJS'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-4605279063789144640</id><published>2010-05-25T13:55:00.000-05:00</published><updated>2010-08-04T23:45:21.309-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><title type='text'>Tidbits</title><content type='html'>&lt;p&gt;As of this morning, &lt;a href="http://jsconf.us/2010"&gt;JSConf 2010&lt;/a&gt; videos are &lt;a href="http://blip.tv/file/3645865"&gt;starting to make their way online&lt;/a&gt;. I'm looking forward to virtually experiencing the Piratey goodness for myself.&lt;/p&gt;

&lt;p&gt;Oh, and I'm starting to fix/update the &lt;a href="http://buyog.com/code/loc/Canvassa/mapper.html"&gt;Canvassa mapping tool&lt;/a&gt;, still needs some optimizations and bugfixes, but at least it's not completely broken anymore... yay?&lt;/p&gt;

&lt;p&gt;Finally, I've recently found myself on an insanely-accelerated timetable to finish my Computational Linguistics MA thesis in the next 3 weeks or so, so you can probably expect my next post or two to reflect that preoccupation. Provided I find anything in the course of writing it that deserves the (slightly) larger platform.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-4605279063789144640?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/4605279063789144640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/tidbits.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4605279063789144640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4605279063789144640'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/tidbits.html' title='Tidbits'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1942101738121517491</id><published>2010-05-22T23:19:00.005-05:00</published><updated>2010-08-04T23:45:21.310-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='cygwin'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Solved: Cannot find -lgcc_s on Cygwin 4.3.4</title><content type='html'>&lt;p&gt;For the past week or so, I've been trying to build the &lt;a href="http://giza-pp.googlecode.com/"&gt;Giza++&lt;/a&gt; language modeling tools on my Windows machines, and have been having quite a bit of trouble. Permissions errors on Windows 7, weird &lt;a href="http://www.cygwin.com/ml/cygwin/2003-07/msg00341.html"&gt;"missing separator" error messages&lt;/a&gt; that were completely unhelpful (it means your text editor has replaced all tabs with spaces), and so on. Compile and build errors that have kept me up late into the night on several occasions lately, but which I was ultimately able to untangle with a little applied Google-Fu.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Despite my best efforts, though, I was stymied by this error:&lt;/p&gt;

&lt;pre class="console"&gt;
g++  -Wall -W -Wno-deprecated -O3 -DNDEBUG -DWORDINDEX_WITH_4_BYTE -DBINARY_SEARCH_FOR_TTABLE optimized/Parameter.o optimized/myassert.o optimized/Perplexity.o optimized/model1.o optimized/model2.o optimized/model3.o optimized/getSentence.o optimized/TTables.o optimized/ATables.o optimized/AlignTables.o optimized/main.o optimized/NTables.o optimized/model2to3.o optimized/collCounts.o optimized/alignment.o optimized/vocab.o optimized/MoveSwapMatrix.o optimized/transpair_model3.o optimized/transpair_model5.o optimized/transpair_model4.o optimized/utility.o optimized/parse.o optimized/reports.o optimized/model3_viterbi.o optimized/model3_viterbi_with_tricks.o optimized/Dictionary.o optimized/model345-peg.o optimized/hmm.o optimized/HMMTables.o optimized/ForwardBackward.o -static -o GIZA++

/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status
make: *** [GIZA++] Error 1
&lt;/pre&gt;

&lt;p&gt;My initial web searches didn't illuminate much: the "-lgcc_s" bit in the error report pointed to a problem with Libgcc, but that library is part of GCC, and Cygwin installs it just fine when you tell it to &amp;mdash; I should know, I've (re)installed Cygwin on two different machines 3 times in the past few days! So, what could the problem possibly be...? Tonight, I finally found the answer, with a nudge in the right direction from &lt;a href="http://collagefactory.blogspot.com/2010/05/cannot-find-lgccs.html"&gt;this blog&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;'-static' option makes gcc to avoid the use of shared libraries. '-static' is supposed to make gcc use -lgcc_s and '-dynamic' to make gcc use -lgcc. Actually, Cygwin and gcc 4.3.4 are not coming with 'libgcc_s.a'. Something's wrong, but I'm not sure here. Anyway, in order to compile, it is necessary to change '-static' to something. For instance, if '-static' was removed, it would be okay!&lt;/blockquote&gt;

&lt;p&gt;This reminded me of something I read in the &lt;a href="http://www.statmt.org/moses_steps.html"&gt;"Getting Started" guide&lt;/a&gt; to Moses, the statistical machine translation system I'm trying to use as part of my Computational Linguistics MA thesis:&lt;/p&gt;

&lt;div style="border: 3px double blue; background-color: lightblue; padding: 5px"&gt;&lt;p&gt;OS X doesn't support static linking (&lt;a href="http://developer.apple.com/qa/qa2001/qa1118.html"&gt;here&lt;/a&gt;'s more info), so we need to tweak two Makefiles.
GIZA++-v2/Makefile:&lt;/p&gt;
&lt;pre class="console"&gt;
15c15
&amp;lt; LDFLAGS = -static
---
&amp;gt; LDFLAGS = 
&lt;/pre&gt;
&lt;p&gt;mkcls-v2/Makefile is OK&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Aside from the questionable logic here ("we need to tweak two Makefiles", but then the second one "is OK"? Hmm, if you say so...), this clicked into place alongside what the first blog said. If OS X doesn't support static linking, I'm willing to bet that Cygwin on Windows doesn't either. I edited the Makefile &amp;mdash; taking care to preserve the tabs on save this time &amp;mdash; and made the suggested change to the LDFLAGS assignment line. This time, when I ran &lt;code&gt;make&lt;/code&gt;, it worked! Problem solved, &lt;em&gt;finally&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, I can go to bed. :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1942101738121517491?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1942101738121517491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/solved-cannot-find-lgccs-on-cygwin-434.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1942101738121517491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1942101738121517491'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/solved-cannot-find-lgccs-on-cygwin-434.html' title='Solved: Cannot find -lgcc_s on Cygwin 4.3.4'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6496811763450147052</id><published>2010-05-04T13:57:00.003-05:00</published><updated>2010-05-05T11:25:36.839-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>JSConf 2010: Final Thoughts and Links</title><content type='html'>&lt;p&gt;Today I saw in my blog reader that Guillermo Rauch over at &lt;a href="http://devthought.com/blog/2010/05/jsconf-2010-slides/"&gt;DevThought&lt;/a&gt; has posted his list of &lt;a href="http://devthought.com/blog/2010/05/jsconf-2010-slides/"&gt;JSConf links&lt;/a&gt;, similar to mine (&lt;a href="http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html"&gt;Day 1&lt;/a&gt; and &lt;a href="http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day_23.html"&gt;Day 2&lt;/a&gt;). He's got a few links I haven't got in mine, but I have some he doesn't, too (he only listed Track A talks). So in the interest of cross-pollination, I've updated my posts and will give him a heads-up of my additions as well, when I can (my work firewall blocks his site for some reason).&lt;/p&gt;

&lt;p&gt;Also, in the interest of pointing out other coverage of the best pirate-themed JavaScript conference on the East Coast, here are a few other blogs that have posted cool wrap-ups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://benalman.com/news/2010/04/jsconf-x/"&gt;Cowboy&lt;/a&gt;, a.k.a. Ben Alman, posted this great summary of the talks he attended, &lt;a href="http://benalman.com/photo/sets/72157623781707905/"&gt;complete with photos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blueskyonmars.com/2010/04/17/jsconf-2010-day-1/"&gt;Kevin Dangoor&lt;/a&gt; posted a similar wrapup to his own blog, with some nice commentary on Day 1 talks.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sauria.com/blog/2010/04/19/jsconf-us/"&gt;Ted Leung&lt;/a&gt; did a great overview of the conference as a whole&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.reybango.com/2010/04/21/jsconf-2010-video-interviews-with-top-javascript-developers/"&gt;Rey Bango&lt;/a&gt; posted a bunch of awesome video interviews he took while attending. Go. Watch. I'll wait.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh, and in only-slightly-related news, &lt;a href="http://www.reddit.com/user/buyog"&gt;I'm now on Reddit&lt;/a&gt;. Don't know that I'll post there much, but thought it was worth mentioning.&lt;/p&gt;

&lt;p&gt;Finally, a note on plans. I think enough people appreciated these "In Case You Missed It" posts, that I'm going to try to keep doing them &amp;mdash; at least when the conference interests me. Here are the next few I've got my eye on covering, time permitting:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;&lt;th&gt;Conference&lt;/th&gt;&lt;th&gt;Date&lt;/th&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.gdc-canada.com/"&gt;GDC Canada&lt;/a&gt;&lt;/td&gt;&lt;td&gt;6-7 May&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://code.google.com/events/io/2010/"&gt;Google I/O&lt;/a&gt;&lt;/td&gt;&lt;td&gt;19-20 May&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://texasjavascript.com/"&gt;TXJS&lt;/a&gt;&lt;/td&gt;&lt;td&gt;5 Jun&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.vslive.com/Home.aspx"&gt;VSLive!&lt;/a&gt;&lt;/td&gt;&lt;td&gt;2-6 Aug&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.gdconline.com/"&gt;GDC Austin&lt;/a&gt;&lt;/td&gt;&lt;td&gt;5-8 Oct&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://jsconf.eu/2010/"&gt;JSConf.eu&lt;/a&gt;&lt;/td&gt;&lt;td&gt;25-26 Sept&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6496811763450147052?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6496811763450147052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/jsconf-2010-final-thoughts-and-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6496811763450147052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6496811763450147052'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/05/jsconf-2010-final-thoughts-and-links.html' title='JSConf 2010: Final Thoughts and Links'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6227041821176729410</id><published>2010-04-28T12:19:00.002-05:00</published><updated>2010-04-28T12:22:43.076-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work-life balance'/><title type='text'>Deep thought of the day</title><content type='html'>&lt;p&gt;Interesting advice from &lt;a href="http://twitter.com/jonathancoulton"&gt;a former code monkey&lt;/a&gt; who quit his job to follow his dreams:&lt;/p&gt;

&lt;blockquote&gt;"If there’s one thing I’ve learned about living a life it’s that you need to keep moving, and if there’s another thing it’s that you really should quit your job every once in a while and take on something new, maybe even something that seems crazy and scares the hell out of you"&lt;/blockquote&gt;&lt;p&gt; - &lt;a href="http://bit.ly/dztScW"&gt;Jonathan Coulton&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Something worth thinking about.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6227041821176729410?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6227041821176729410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/deep-thought-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6227041821176729410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6227041821176729410'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/deep-thought-of-day.html' title='Deep thought of the day'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6641213537309509920</id><published>2010-04-25T21:38:00.001-05:00</published><updated>2010-04-25T21:42:35.836-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>How to move to Blogspot and keep your blog on your own domain</title><content type='html'>&lt;p&gt;Recently faced with the problem of how to have my blogs remain in their pre-existing locations while complying with Blogger's &lt;a href="http://pugadngbuyog.blogspot.com/2010/02/well-darn.html"&gt;mandatory move away from FTP publishing&lt;/a&gt;, I think I've found a pretty easy solution: if you're on a &lt;a href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29"&gt;LAMP&lt;/a&gt; server (which I suspect most of you are; it's nearly ubiquitous), it's as easy as removing all other index.* files and creating a new index.php file in the appropriate folder, and dropping in these 5 lines of PHP code, changing the URL in the first line as appropriate:&lt;/p&gt;

&lt;pre class="brush:php"&gt;
$session = curl_init("http://your.web.address");
curl_setopt($session, CURLOPT_HEADER, 0);
$content = curl_exec($session);
curl_close($session);
echo $content;
&lt;/pre&gt;

&lt;p&gt;&lt;a href="php.net/manual/en/book.curl.php"&gt;cURL&lt;/a&gt; is the secret sauce in there, and I could go into a lot more depth, but if you don't need to worry about authentication or anything more complex than a simple page-fetch, there's no need. I allow the post-comments and labels pages to link directly to Blogspot, and I use &lt;a href="http://feedburner.google.com/fb/a/dashboard?id=10159fccn0o5tujafcg0lmvttg&amp;gsessionid=_N9QwThM79e3B9fowToWkw"&gt;Feedburner&lt;/a&gt; to host my RSS feeds, so this simple solution gets me 95% of the way there. The rest is just resource-management and wise template design.&lt;/p&gt;

&lt;p&gt;I love it when something that looks like it'll be difficult turns out to be so easy! But please, if I'm doing anything that opens me up to possible security problems (I don't think I am, but...), please let me know in the comments.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6641213537309509920?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6641213537309509920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/how-to-move-to-blogspot-and-keep-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6641213537309509920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6641213537309509920'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/how-to-move-to-blogspot-and-keep-your.html' title='How to move to Blogspot and keep your blog on your own domain'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8253970286830721473</id><published>2010-04-23T10:03:00.008-05:00</published><updated>2010-05-12T08:02:18.591-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><title type='text'>In Case You Missed It: JSConf.us 2010 (day 2)</title><content type='html'>&lt;p&gt;Here's part 2 of my attempt to distill the juicy bits from last weekend's JSConf presentations (&lt;a href="http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html"&gt;here's&lt;/a&gt; part 1). Of course, this is only a pale imitation of the experience of &lt;em&gt;actually attending&lt;/em&gt; the conference, but hopefully it will serve to keep you, dear readers, up to speed on the latest, bleeding-edge movements within the JavaScript community. Let's get to it:&lt;/p&gt;

&lt;h3&gt;In Case You Missed It: JSConf.us 2010&lt;/h3&gt;
&lt;h4&gt;Day 2: Sunday, April 18, 2010&lt;/h4&gt;

&lt;table width="100%"&gt;
&lt;thead&gt;&lt;th&gt;Speaker(s)&lt;/th&gt;&lt;th&gt;Topic&lt;/th&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK A&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/onkis"&gt;Mike Ball&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/etgryphon"&gt;Evin Grano&lt;/a&gt;&lt;/td&gt;&lt;td&gt;SproutCore: Introducing &lt;a href="http://blog.sproutcore.com/post/535950751/introducing-greenhouse"&gt;Greenhouse&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/DmitryBaranovsk"&gt;Dmitry Baranovskiy&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/Dmitry.Baranovskiy/raphal-js-conf"&gt;Raphaël the Great&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/commonjs"&gt;CommonJS&lt;/a&gt; Panel Discussion&lt;/td&gt;&lt;td&gt;JavaScript Outside of the Browser - Where it is and where it's going! (wait for the video)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://makinde.adeagbo.com/"&gt;Makinde Adeagbo&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/makinde/javascript-primer"&gt;Primer: Facebook's 2k of JavaScript to power (almost) all interactions&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jdalton"&gt;John-David Dalton&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/johndaviddalton/jsconf-all-you-can-leet"&gt;All you can leet - Coding for performance, CSS engines, and sandboxed natives&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;s&gt;Felix Geisendoerfer&lt;/s&gt;&lt;/td&gt;&lt;td&gt;&lt;s&gt;Dirty NoSQL&lt;/s&gt; (cancelled due to Icelandic ash)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jedschmidt"&gt;Jed Schmidt&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/tr4nslator/sets/72157623883700702/"&gt;A (fab) approach to web apps&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/justinbmeyer"&gt;Justin Meyer&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://paulirish.com/lovesyou/jmvc-jsconf-notes-2010.jpg"&gt;Thin Server Architecture and JavaScriptMVC 3.0&lt;/a&gt; (&lt;a href="http://javascriptmvc.com/"&gt;site&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://stevesouders.com/blog/"&gt;Steve Souders&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/souders/jsconf-us-2010"&gt;The Best of Steve&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/maraksquires"&gt;Marak Squires&lt;/a&gt;, &lt;a href="http://twitter.com/ScurvyConf"&gt;@ScurvyConf&lt;/a&gt; Master&lt;/td&gt;&lt;td&gt;&lt;a href="http://hook.io/"&gt;hook.io&lt;/a&gt;: the crowd favorite from &lt;a href="http://jsconf.us/2010/scurvy.html"&gt;ScurvyConf&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/zoompf"&gt;Billy Hoffman&lt;/a&gt;&lt;/td&gt;&lt;td&gt;JavaScript's Evil Side (introducing &lt;a href="http://zoompf.com/"&gt;Zoompf&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;/be (&lt;a href="http://twitter.com/brendaneich"&gt;Brendan Eich&lt;/a&gt;)&lt;/td&gt;&lt;td&gt;"An Introduction to JavaScript" (was actually a discussion of JS's future; wait for the video)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/AlexRussell"&gt;Alex Russell&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://alex.dojotoolkit.org/10/jsconf/gcf.html"&gt;Google Chrome Frame&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK B&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jonathanjulian"&gt;Jonathan Julian&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/jonathanjulian/hangoverjs"&gt;Hangover.js&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/VinylFox"&gt;Shea Frederick&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.extjs.com/"&gt;Ext JS&lt;/a&gt; App UI Morphing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/getify"&gt;Kyle Simpson&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/shadedecho/javascript-architecture-the-front-and-the-back-of-it-3518425"&gt;Dude wheres my UI Architecture&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Adam Moore&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/apmoore/running-yui-3-on-nodejs"&gt;Running YUI 3 on Node.js&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/deanlandolt"&gt;Dean Landolt&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="www.sitepen.com/blog/2010/01/22/introducing-pintura/"&gt;Pintura&lt;/a&gt;, &lt;a href="http://github.com/kriszyp/perstore"&gt;Perstore&lt;/a&gt; and Awesome-Oriented Persistence&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/suvajitgupta/"&gt;Suvajit Gupta&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Colossal JavaScript&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/cramforce/"&gt;Malte Ubl&lt;/a&gt;&lt;/td&gt;&lt;td&gt;JavaScript - The Private Parts&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/furf"&gt;David Furfero&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/furf/making-ajax-sexy-jsconf-2010"&gt;Sexy.js Boots Bundles Binding&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.linkedin.com/pub/rob-tsuk/2/47/834"&gt;Rob Tsuk&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Mojo: Developing and Building a touch UI framework for mobile using the Web (or, Writing webOS Services in JavaScript)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/goonieiam"&gt;Gonzalo Cordero&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/gonzalocordero/creating-custom-modules-using-yui3"&gt;Creating custom modules using YUI3&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;s&gt;&lt;a href="http://twitter.com/amorgaut"&gt;Alexandre Morgaut&lt;/a&gt;&lt;/s&gt;&lt;/td&gt;&lt;td&gt;&lt;s&gt;Taking over the enterprise one hook at a time&lt;/s&gt; (cancelled due to ash)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/janl"&gt;Jan Lehnardt&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://blog.couch.io/post/399191405/screencast-demoing-some-new-couchapp-jquery"&gt;Evently&lt;/a&gt;: Declarative &lt;a href="http://couchdb.org"&gt;CouchDB&lt;/a&gt; Applications that practically write themselves&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brianleroux"&gt;Brian LeRoux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="www.slideshare.net/brianleroux/scurvyconf"&gt;PhoneGap&lt;/a&gt; Hack Around&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tom, Jenn, Adam &amp;amp; Derek&lt;/td&gt;&lt;td&gt;JavaScript. @$#*% yeah. (wait for the video)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/raycmorgan"&gt;Ray Morgan&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://github.com/janl/mustache.js/"&gt;Mustache&lt;/a&gt; is simplifying your templates&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/brianleroux"&gt;Brian LeRoux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;best of &lt;a href="http://wtfjs.com/"&gt;wtfjs&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;As with &lt;a href="http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html"&gt;Part 1&lt;/a&gt;, this is what I've been able to find so far. &lt;s&gt;A lot of the Track B and panel discussions were largely unscripted, and I'm pretty sure Track B wasn't taped, so&lt;/s&gt; A lot of the slide decks haven't shown up online yet, so I've tried to link to the most relevant blogs talking about the topics in question. In a few instances (e.g. Rob Tsuk's talk on Mojo/webOS development for Palm), I've failed to find much of anything relevant online, so we'll have to wait and see what (if anything) eventually finds its way online. This is of course one of the big reasons why actually &lt;em&gt;attending&lt;/em&gt; a conference is preferable to just reading about it after the fact, and I highly encourage you to take that opportunity when it presents itself.&lt;/p&gt;

&lt;p&gt;As before, if there are slide decks from other talks online that I don't have linked here, please note it in the comments below, and I'll update accordingly.&lt;/p&gt;

&lt;p&gt;Updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;2010-04-23&lt;/em&gt;: &lt;a href="http://twitter.com/getify"&gt;@Getify&lt;/a&gt; corrected my bad assumption about the Track B talks, so I've revised the last paragraph.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;2010-04-26&lt;/em&gt;: &lt;a href="http://twitter.com/goonieiam"&gt;Gonzalo Cordero&lt;/a&gt; just posted his YUI3 talk slides, so I've added them.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;2010-04-27&lt;/em&gt;: &lt;a href="http://www.blogger.com/profile/05613993942942218830"&gt;Dude&lt;/a&gt; sent me the link to JDalton's slide deck, so I've added it to the Track A listing.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;2010-05-05&lt;/em&gt;: &lt;a href="http://twitter.com/paul_irish/status/13431426072"&gt;Paul Irish&lt;/a&gt; graciously shared his copy of Justin Meyer's JavascriptMVC notes, so I've linked them in.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;2010-05-12&lt;/em&gt;: &lt;a href="http://twitter.com/sh1mmer"&gt;Tom Hughes-Croucher&lt;/a&gt; posted his JSConf recap on the &lt;a href="http://developer.yahoo.net/blog/archives/2010/05/jsconfus_the_pirate_edition.html"&gt;YDN Blog&lt;/a&gt;, and it included refs to a couple of the Yahoo presentations that I'd been missing. They're now linked into the table.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8253970286830721473?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8253970286830721473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day_23.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8253970286830721473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8253970286830721473'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day_23.html' title='In Case You Missed It: JSConf.us 2010 (day 2)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-3955126479249560780</id><published>2010-04-20T11:33:00.020-05:00</published><updated>2010-05-12T08:03:33.838-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='icymi'/><title type='text'>In Case You Missed It: JSConf.us 2010 (day 1)</title><content type='html'>&lt;p&gt;Last weekend, the second annual &lt;a href="http://jsconf.us/2010/"&gt;JSConf&lt;/a&gt; conference was held in Washington DC. If you've been reading for a while, you know &lt;a href="http://palagpat-coding.blogspot.com/2009/04/jsconf-2009.html"&gt;I went last year&lt;/a&gt; and &lt;a href="http://palagpat-coding.blogspot.com/2009/04/jsconf-tweets.html"&gt;&lt;em&gt;loved&lt;/em&gt; it&lt;/a&gt;. This year, unfortunately, my work and personal schedules conflicted, so this week I'm playing catch-up: looking over the &lt;a href="http://jsconf.us/2010/schedule.html"&gt;published schedule&lt;/a&gt;, then picking through the &lt;a href="http://twitter.com/#search?q=%23jsconf"&gt;Twitter&lt;/a&gt; &lt;s&gt;stream&lt;/s&gt;firehose to find the presenters, and where possible, the slides they presented.&lt;/p&gt;

&lt;p&gt;In doing this, it occurred to me that there may be value in what I'm putting together, at least until the conference's producers can catch their breath and upload the session videos (which, experience tells me, might take a little while). With that introduction, I present to you the first of what may become an ongoing series, which I'm calling &lt;em&gt;&lt;a href="http://palagpat-coding.blogspot.com/search/label/icymi"&gt;In Case You Missed It&lt;/a&gt;&lt;/em&gt;:&lt;/p&gt;

&lt;h3&gt;In Case You Missed It: JSConf.us 2010&lt;/h3&gt;
&lt;h4&gt;Day 1: Saturday, April 17, 2010&lt;/h4&gt;

&lt;table width="100%"&gt;
&lt;thead&gt;&lt;th&gt;Speaker(s)&lt;/th&gt;&lt;th&gt;Topic&lt;/th&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK A&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/douglascrockford/really-javascript-3771995"&gt;Really. JavaScript.&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/mitchoyoshitaka"&gt;Michael Erlewine&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/mitcho/the-latest-from-mozilla-jetpack"&gt;Mozilla's JetPack&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://benzilla.galbraiths.org/"&gt;Ben Galbraith&lt;/a&gt;, &lt;a href="http://twitter.com/dalmaer"&gt;Dion Almaer&lt;/a&gt;, &amp;amp; &lt;a href="http://twitter.com/mattsmcnulty"&gt;Matt McNulty&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/dion/the-mobile-web-2010-jsconf"&gt;Solving Device Fragmentation: How Do You Support 12,320 Different Mobile Platforms?&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/tolmasky"&gt;Francisco Tolmasky&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://github.com/280north/socratic"&gt;Socratic&lt;/a&gt;: Documentation Done Right&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/Jennlukas"&gt;Jenn Lukas&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/JennLukas/javascript-and-web-standards-sitting-in-a-tree"&gt;JavaScript and Web Standards Sitting in a Tree&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/ryah"&gt;Ryah Dahl&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://nodejs.org/jsconf2010.pdf"&gt;Less is More in Node.js&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/tobeytailor"&gt;Tobias Schneider&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/ConfEcho/flash-is-dead-long-live-flash"&gt;Flash is dead, long live Flash!&lt;/a&gt; (&lt;a href="github.com/tobeytailor/gordon"&gt;Gordon&lt;/a&gt;: a pure-JS Flash replacement)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/anutron"&gt;Aaron Newton&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/guest2ee5e2c/programming-to-patterns-presentation"&gt;Programming To Patterns&lt;/a&gt; (per &lt;a href="http://devthought.com"&gt;Guillermo Rauch&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/sh1mmer"&gt;Tom Hughes-Croucher&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/sh1mmer/yql-tutorial"&gt;Piratin' the YQL way&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/aq"&gt;Aaron Quint&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://swinger.quirkey.com/#/preso/aq-jsconf/display/1"&gt;Making Bacon: Making Code&lt;/a&gt; (&lt;a href="http://www.vimeo.com/11009641"&gt;video&lt;/a&gt;, &lt;a href="http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/"&gt;blog&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td colspan="2"&gt;&lt;strong&gt;TRACK B&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/voodootikigod"&gt;Chris Williams&lt;/a&gt; (JSConf co-creator)&lt;/td&gt;&lt;td&gt;How I Pulled off JSConf&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/binary42"&gt;Brian Mitchell&lt;/a&gt;&lt;/td&gt;&lt;td&gt;JavaScript's Twin (&lt;a href="http://www.lua.org"&gt;Lua&lt;/a&gt; for JavaScript developers)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://github.com/jashkenas/"&gt;Jeremy Ashkenas&lt;/a&gt;&lt;/td&gt;&lt;td&gt;A Cup of &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeeScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/paul_irish"&gt;Paul Irish&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.slideshare.net/paul.irish/progressive-advancement-in-web8"&gt;Progressive Advancement on the High Seas of Web8&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/zii/"&gt;Zach Carter&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://github.com/zaach/zii-jsconf2010-talk"&gt;Build your own programming language with JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/mahemoff"&gt;Michael Mahemoff&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://prez.mahemoff.com/jsconf2010-spahacks.html"&gt;The Lost Hacks Ridiculous Browser Tricks from the World of Single-Page Applications&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/nonken/"&gt;Nikolai Onken&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The browser controlling hardware real pirate hackery&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/nonken/"&gt;Nikolai Onken&lt;/a&gt; &amp;amp; &lt;a href="http://tobias.klpstn.com/"&gt;Tobias von Klipstein&lt;/a&gt;&lt;/td&gt;&lt;td&gt;What the heck are &lt;a href="http://www.quirksmode.org/blog/archives/2010/03/html5_apps.html"&gt;HTML5 Apps&lt;/a&gt;?&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jeresig"&gt;John Resig&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Call for a better DOM API&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/dangoor"&gt;Kevin Dangoor&lt;/a&gt; &amp;amp; Patrick Walton&lt;/td&gt;&lt;td&gt;&lt;a href="https://bespin.mozillalabs.com/"&gt;Bespin&lt;/a&gt;: the extensible in-browser code editor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/jvgogh"&gt;Jeffrey Van Gogh&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://blogs.msdn.com/jeffva/archive/2010/04/14/node-js-bindings-for-rxjs.aspx"&gt;The Reactive Extensions for JavaScript&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/f1lt3r"&gt;Alistair MacDonald&lt;/a&gt;&lt;/td&gt;&lt;td&gt;WebGL Demo Overload&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://twitter.com/rektide"&gt;Matthew Fowle&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://rektide.voodoowarez.com/2010/4/state.of.tubes.mfowle.odp"&gt;New Web Architecture&lt;/a&gt;&amp;nbsp;&lt;a href="#icymi_f1"&gt;*&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;As of this morning, this is what I could find. If there are slide decks from other talks online that I don't have linked here, please note it in the comments below, and I'll update accordingly.&lt;/p&gt;

&lt;p&gt;Footnotes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name="icymi_f1"&gt;&lt;/a&gt;This is actually Matthew Fowle's ScruvyConf presentation; he did his Track B presentation slides &lt;a href="http://twitter.com/getify/status/12360909268"&gt;on the fly&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;2010/04/20 1:12pm&lt;/em&gt; - &lt;a href="http://www.blogger.com/profile/14502801001540923600"&gt;akahn&lt;/a&gt; mentioned in the comments that the title of Aaron Quint's talk was wrong; I took the original published name, but the slides carry a different one. The table now reflects both.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;2010/04/20 2:35pm&lt;/em&gt; - Looking over this table, I realized I'd left off the entire back half of Track B. It's there now.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;2010/04/20 10:13pm&lt;/em&gt; - &lt;a href="http://www.abcedmindedness.com/index.html"&gt;Ray&lt;/a&gt; mentioned in the comments that Jed Schmidt's (fab) talk was moved to Day 2 Track A, so I've removed it from the Track B list here.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;2010/04/25&lt;/em&gt; - &lt;a href="http://twitter.com/rektide"&gt;Matthew Fowle&lt;/a&gt; sent me his contact info, so I've linked him up above.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;2010/04/28&lt;/em&gt; - &lt;a href="http://twitter.com/voodootikigod"&gt;Chris Williams&lt;/a&gt; has provided me more of the slide decks that the presenters gave to the JSConf organizers. I will be putting these online and linking to them as they become available; this morning I've linked up Tobias Schneider's Gordon slides.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;2010/05/04&lt;/em&gt; - &lt;a href="http://devthought.com"&gt;Guillermo Rauch over at DevThought&lt;/a&gt; has posted his list of JSConf slides, and had a few I'd missed; I've added these now.&lt;/li&gt;

&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-3955126479249560780?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/3955126479249560780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3955126479249560780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3955126479249560780'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/04/in-case-you-missed-it-jsconfus-2010-day.html' title='In Case You Missed It: JSConf.us 2010 (day 1)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6727797957841915260</id><published>2010-03-05T01:03:00.001-05:00</published><updated>2010-03-05T01:08:54.309-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Cloning Zelda: Meet Canvassa's Little Brother</title><content type='html'>&lt;img src="http://buyog.com/code/images/loc_littleBro.png" alt="Link, meet Link..."/&gt;

&lt;p&gt;I recently received an email from &lt;a href="http://blog.rag.no/"&gt;Rune Andreas Grimstad&lt;/a&gt;, requesting my permission to use some of the data assets I created for &lt;a href=""&gt;Canvassa&lt;/a&gt; (specifically the map data and sprite tiles). You see, he's doing &lt;a href="http://blog.rag.no/?tag=/silvertile"&gt;a Zelda clone of his own&lt;/a&gt; &amp;mdash; for Silverlight (like his blog title suggests, "It should be fun").&lt;/p&gt;

&lt;p&gt;Anyway, I'm happy to share... especially since the game design and sprites aren't mine in the first place! ;) But even my code is there to be shared &amp;mdash; that's why I put it on &lt;a href="http://github.com/buyog/Canvassa"&gt;GitHub&lt;/a&gt;, after all. Anyone else who wants to use that stuff can either fork the Github repo directly, or just grab it and use it. All I ask in return is a quick note like Rune's, to let me know about the project, so I can link back to it and throw a few clicks your direction.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6727797957841915260?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6727797957841915260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/03/cloning-zelda-meet-canvassas-little.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6727797957841915260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6727797957841915260'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/03/cloning-zelda-meet-canvassas-little.html' title='Cloning Zelda: Meet Canvassa&apos;s Little Brother'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-3377929208521467089</id><published>2010-02-13T15:33:00.002-05:00</published><updated>2010-02-13T16:07:50.960-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='MUGEN'/><title type='text'>MUGEN plugin for SyntaxHighlighter</title><content type='html'>&lt;p&gt;&lt;a href="http://buyog.com/code/2010/02/cloning-zelda-whither-chrome.html"&gt;Earlier today&lt;/a&gt;, I uploaded my first blog post that needed to include MUGEN source code. Between this site and my &lt;a href="http://buyog.com/MUGEN"&gt;MUGEN-centric blog&lt;/a&gt;, I suspect it won't be my last. So, I took the time to put together a plugin for Alex Gorbatchev's excellent &lt;a href="http://alexgorbatchev.com"&gt;SyntaxHighlighter&lt;/a&gt;, and now I can post blocks of MUGEN code that get auto-magically highlighted, like this:&lt;/p&gt;
&lt;pre class="brush: mugen"&gt;
[State 1000, fireball]
type = Projectile
trigger1 = AnimElem = 1
ProjID = 1010
projanim = 1010
projhitanim = 1020
projremanim = 1020
projcancelanim = 1020
velocity = 6,0
offset = 0,-80
; HitDef
attr = S,SP
hitflag = MAF
guardflag = MA
animtype = medium
priority = 4,Hit
damage = 40,5
pausetime = 4,4
sparkno = S9992
guard.sparkno = 0
hitsound = S2,2
guardsound = S3,0
ground.type = Low
ground.slidetime = 8
ground.hittime  = 8
ground.velocity = -6,0
air.velocity = -2,-2
&lt;/pre&gt;
&lt;p&gt;Anyway, I thought this was worth sharing, so for anyone interested, you can download a copy of the MUGEN brush for SyntaxHighter &lt;a href="http://buyog.com/code/sh/scripts/shBrushMugen.js"&gt;right here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-3377929208521467089?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/3377929208521467089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/mugen-plugin-for-syntaxhighlighter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3377929208521467089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3377929208521467089'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/mugen-plugin-for-syntaxhighlighter.html' title='MUGEN plugin for SyntaxHighlighter'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7692081713038728775</id><published>2010-02-13T10:19:00.002-05:00</published><updated>2010-06-03T21:18:30.448-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='MUGEN'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Fixing Chrome</title><content type='html'>&lt;img src="http://buyog.com/code/images/loc_sadChrome.png" alt="Chrome displaying a 'broken' tab"/&gt;
&lt;p&gt;This week, an epic snowfall in the mid-Atlantic states kept me home from work for four straight days, giving me lots of spare time to &lt;a href="http://buyog.com/2010/02/blizzard.html"&gt;play with my kids&lt;/a&gt;, and work on some &lt;a href="http://buyog.com/MUGEN/2010/02/snowed-in.html"&gt;side&lt;/a&gt; &lt;a href="http://buyog.com/MUGEN/2010/02/snow-day-2.html"&gt;projects&lt;/a&gt;. One of these was addressing a long-standing problem with Canvassa: namely, why it was broken in Google's Chrome browser.&lt;/p&gt;

&lt;p&gt;The initial impetus for this task came from a &lt;a href="http://buyog.com/code/2010/01/happy-birthday-canvassa.html#c3458976680111985726"&gt;comment&lt;/a&gt; left by &lt;a href="http://quadracycle.blogspot.com/"&gt;Gaby de Wilde&lt;/a&gt; on a recent blog entry, in which he asked if I knew why the project wasn't working on Chrome. I was a bit embarrassed to admit that I wasn't sure, so it drove me to look into why.&lt;/p&gt;

&lt;h4&gt;Step 1: Get My Feelings Hurt&lt;/h4&gt;

&lt;p&gt;First stop was to fire up Chrome and open the JavaScript Console. Then I loaded up &lt;a href="http://buyog.com/code/loc/Canvassa/"&gt;the main Canvassa URL&lt;/a&gt; and examined the error console. Sure enough, after loading several of my class files, it barfed on &lt;code&gt;Game.js&lt;/code&gt;. Unfortunately, due to the nature of Dojo's on-demand script loader, the console didn't actually tell me WHY that class didn't load.&lt;/p&gt;

&lt;p&gt;Given that the error console wasn't being very forthcoming, my next stop was Douglas Crockford's &lt;a href="http://www.jslint.com/"&gt;JSLint&lt;/a&gt; code-validation tool. Needless to say, it lived up to its billing and "hurt my feelings," at least a little bit. It turns out I was cutting quite a few corners that Crockford argues shouldn't be cut: &lt;a href="http://www.jslint.com/lint.html#semicolon"&gt;omitting semicolons&lt;/a&gt;, &lt;a href="http://www.jslint.com/lint.html#var"&gt;defining my variables wrong&lt;/a&gt;, and &lt;a href="http://www.jslint.com/lint.html#forin"&gt;not filtering for..in blocks&lt;/a&gt; seem to be my most common errors. Firefox and IE don't care about this sort of thing; they just blithely ignore it and carry on with what you &lt;em&gt;intended&lt;/em&gt; to say, instead of making a scene in front of the entire classroom, going on about how "rules are for everyone, including you, &lt;a href="http://www.youtube.com/watch?v=dVAOrhZR6Pk"&gt;Mister Potter&lt;/a&gt;."&lt;/p&gt;

&lt;p&gt;Ahem.&lt;/p&gt;

&lt;h4&gt;Step 2: Learn Something About Chrome's Canvas Implementation&lt;/h4&gt;

&lt;p&gt;Once JSLint had issued me 50 demerits and was satisfied with the quality of my &lt;code&gt;Game.js&lt;/code&gt; class file, I uploaded the fixed copy to my web server and went back to Chrome to reload the main page. Success... for a few minutes anyway. After playing the game for a few minutes, I began to notice that the game would, at seemingly random times, appear to "freeze up" and stop drawing its sprites. After a few seconds, though, they would all come back and the game would resume. Opening the JavaScript console again, I noticed that the freezeup occurred every time the app generated a flood of these errors:&lt;/p&gt;

&lt;blockquote&gt;Error drawing game sprites: DOMCoreException [in game_drawSprites(default)]&lt;/blockquote&gt;

&lt;p&gt;I added some additional logging to the &lt;code&gt;game_drawSprites()&lt;/code&gt; function, and was able to determine that the exception was occurring in two cases: when Leevers or Zolas went under the ground/water, and when Link killed monsters. Looking for commonalities in those two cases, I found the answer: in both the "digger"-type monsters' animations, I defined the "under water/ground" animation &amp;mdash; which should be invisible to the player &amp;mdash; by specifying the animation frame's sprite coordinates as outside the boundaries of the source image. Looking in &lt;code&gt;&lt;a href="http://buyog.com/code/loc/Canvassa/loc/monster/_base.js"&gt;monster/_base.js&lt;/a&gt;&lt;/code&gt;, the base class for all monsters, I saw that I was doing this same thing in the default monster-death animation:&lt;/p&gt;

&lt;pre class="brush: javascript"&gt;
// /loc/monster/Zola.js: 'underwater' animation definition:
  this._stateDefs[4] = { name: 'underwater', ... anim: [
     [ {x:900,y:900,t:120} ]
  ]};

// note that the monsters.png image is 160x304 pixels, so (900,900) is off the edge

// /loc/monster/_base.js: 'die' animation definition:
  { name: 'die', ... anim: [
    [ {x:64,y:16,t:6},{x:80,y:16,t:3},{x:200,y:16,t:20} ]
  ]}

// again, (200,16) is beyond the 160x304 edge of monsters.png
&lt;/pre&gt;

&lt;p&gt;When I originally set up the sprite animation system, I thought I was being &lt;em&gt;terribly&lt;/em&gt; clever to define "invisible" animation frames in this way. My good buddy Firefox just ignored these calls, or at the very least failed quietly, so no sprite would be displayed for that animation tick. Chrome, however, doesn't see this as clever at all: if you try to pass invalid x,y coordinates to Canvas's 2d context object's &lt;code&gt;drawImage()&lt;/code&gt; function, it throws a big, loud exception.&lt;/p&gt;

&lt;p&gt;Of course, my approach had one other problem as well: if I ever expanded the monster sprite tile image to include more sprites, these supposedly "invisible" animations could suddenly be showing frames of some other sprite's animations! Yeah... bad idea.&lt;/p&gt;

&lt;h4&gt;Step 3: Go With What I Know&lt;/h4&gt;

&lt;p&gt;As with &lt;a href="http://buyog.com/code/2009/12/cloning-zelda-harmful-changes.html"&gt;my last Canvassa update&lt;/a&gt;, the solution to this problem came to me by way of my &lt;a href="http://buyog.com/MUGEN"&gt;MUGEN&lt;/a&gt; experience. With that game engine, the way you define an "invisible" animation frame is by using a sprite index of -1 (note that MUGEN's animation frame format is &lt;code&gt;spriteX, spriteY, offsetX, offsetY, time&lt;/code&gt;):&lt;/p&gt;

&lt;!-- brush: MUGEN would be nice... --&gt;
&lt;pre class="brush: mugen"&gt;
; teleport: disappear and reappear behind my opponent
[Begin Action 1200]
1200,0, 0,0, 5
1200,1, 0,0, 5
1200,2, 0,0, 5
-1,-1, 0,0, 20  ; invisible for 20 ticks before re-appearing
1200,3, 0,0, 5
1200,4, 0,0, 5
1200,5, 0,0, 5
&lt;/pre&gt;

&lt;p&gt;So, adopting this convention, I made the following, small changes to my code:&lt;/p&gt;

&lt;pre class="brush: javascript"&gt;
// /loc/Sprite.js: added this single line to draw():
   if (cut.x === -1 || cut.y === -1) { return; } // (-1 means "don't draw me")

// /loc/monster/Zola.js: changed the 'underwater' animation definition to:
  this._stateDefs[4] = { name: 'underwater', ... anim: [
     [ {x:-1,y:-1,t:120} ]
  ]};

// /loc/monster/_base.js: 'die' animation definition:
  { name: 'die', ... anim: [
    [ {x:64,y:16,t:6},{x:80,y:16,t:3},{x:-1,y:-1,t:20} ]
  ]}
&lt;/pre&gt;

&lt;p&gt;Once I made those changes and uploaded them to my server, I reloaded the game url in Chrome, and it ran without a hitch. Go on, &lt;a href="http://buyog.com/code/loc/Canvassa/"&gt;see for yourself&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So MUGEN saves the day (again). I'm always pleasantly surprised when experience in one realm helps me solve problems in another, but considering how often it happens, I really shouldn't be. Experience is experience... no matter what language or platform it comes from.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7692081713038728775?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7692081713038728775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/cloning-zelda-whither-chrome.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7692081713038728775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7692081713038728775'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/cloning-zelda-whither-chrome.html' title='Cloning Zelda: Fixing Chrome'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-297232520352433497</id><published>2010-02-01T10:03:00.002-05:00</published><updated>2010-08-04T23:45:21.311-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EFR'/><category scheme='http://www.blogger.com/atom/ns#' term='methodology'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><title type='text'>Why data transformations are hard (part 2)</title><content type='html'>&lt;h4&gt;Previously, on Palagpat Coding...&lt;/h4&gt;
&lt;p&gt;In &lt;a href="http://buyog.com/code/2010/01/why-data-transformations-are-hard-part.html"&gt;Part 1&lt;/a&gt; of this post, I talked about how I was going to attack my task of converting an XML-based format for file transcription (&lt;a href="http://www.xces.org/"&gt;XCES&lt;/a&gt;) into the flat-but-structured EFR-segfile format. At the end of the day, I'd gone with a quick-and-dirty solution in Visual Basic 6, as both XSLT and my &lt;a href="http://buyog.com/code/downloads.php#Batleth"&gt;Bat'leth&lt;/a&gt; tool seemed to fall short. Here's a sample of the input and output of that effort:&lt;/p&gt;

&lt;pre class="brush: xml"&gt;
&lt;!-- XCES input file --&gt;
  &lt;s id="1"&gt;
    &lt;time id="T1S" value="00:00:38,785"&gt;&lt;/time&gt;
    &lt;w id="1.1"&gt;Lunchtime&lt;/w&gt;
    &lt;w id="1.2"&gt;!&lt;/w&gt;
    &lt;time id="T1E" value="00:00:40,184"&gt;&lt;/time&gt;
  &lt;/s&gt;
&lt;/pre&gt;

&lt;pre class="brush: text"&gt;
// EFR-segfile output:
0-1164 (00:00:00:00 - 00:00:38:24)
Scene 1: T1S
//T: Lunchtime!
&lt;/pre&gt;

&lt;p&gt;As I mentioned last time, I took this EFR-segfile output and loaded it up in my EFR authoring software to test the segment boundaries, and found that it was off... not &lt;em&gt;hugely&lt;/em&gt; off at the outset, just a few seconds... but things very quickly went off the rails. For example, by the end of Chapter 2 (just 13 minutes into the film), my segfile segments were already off by over 7 minutes!&lt;/p&gt;

&lt;pre class="brush: text"&gt;
37020-37231 (00:20:34:00 - 00:20:41:01)
Scene 417: T303S
//T: Come on, before you catch a real cold.
//N: actual film time: 00:13:27-00:13:30
&lt;/pre&gt;

&lt;p&gt;Clearly, this won't do.&lt;/p&gt;

&lt;h4&gt;What happened?&lt;/h4&gt;

&lt;p&gt;Looking things over, I realized a couple of mistakes right away: First, I had assumed the XCES files covered the full film, so I started at frame 0. However, the first dialog in the film doesn't occur until about 40 seconds in, so my output started off wrong by that much. Secondly, I started each subsequent clip from the endpoint of the previous one, thus ignoring any segments of the movie that didn't involve spoken dialog, so as the film progressed, the timestamps got more and more wrong.&lt;/p&gt;

&lt;p&gt;At this point I took another look at my &lt;a href="http://buyog.net/files/4759_137270_188200_the_goonies.xml.gz"&gt;original XCES file&lt;/a&gt;, and it hit me that there are actually two, overlapping data structures at play:&lt;/p&gt;

&lt;pre class="brush: xml"&gt;
  &lt;s id="733"&gt;
    &lt;time id="T516S" value="00:35:20,209"&gt;&lt;/time&gt; &lt;!-- T516 Start --&gt;
    &lt;w id="733.1"&gt;Get&lt;/w&gt;
    &lt;w id="733.2"&gt;down&lt;/w&gt;
    &lt;w id="733.3"&gt;,&lt;/w&gt;
    &lt;w id="733.4"&gt;guys&lt;/w&gt;
    &lt;w id="733.5"&gt;.&lt;/w&gt;
  &lt;/s&gt;
  &lt;s id="734"&gt;
    &lt;w id="734.1"&gt;Get&lt;/w&gt;
    &lt;w id="734.2"&gt;down&lt;/w&gt;
    &lt;w id="734.3"&gt;.&lt;/w&gt;
    &lt;time id="T516E" value="00:35:21,562"&gt;&lt;/time&gt; &lt;!-- T516 End --&gt;
  &lt;/s&gt;
&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; tags, which I thought represented &lt;em&gt;segments&lt;/em&gt;, instead appear to represent individual &lt;em&gt;sentences&lt;/em&gt;. (with the &lt;code&gt;&amp;lt;w&amp;gt;&lt;/code&gt; tags representing individual &lt;em&gt;words&lt;/em&gt;... seems rather obvious in retrospect). When I looked at the format last time, I didn't give any thought to why the &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; elements sometimes came at the beginning of a sentence and sometimes at the end, but in my review I noticed a consistent trend: the instances that occur as the first child of an &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; element have an id ending in &lt;i&gt;S&lt;/i&gt;, and those that are the &lt;em&gt;last&lt;/em&gt; child of an &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; element have an id ending in &lt;i&gt;E&lt;/i&gt;... &lt;i&gt;S&lt;/i&gt; for "Start", and &lt;i&gt;E&lt;/i&gt; for "End."  So the XML structure of &lt;code&gt;&amp;lt;s&amp;gt;entences&lt;/code&gt; and &lt;code&gt;&amp;lt;w&amp;gt;ords&lt;/code&gt; has a sort of a &lt;em&gt;superstructure&lt;/em&gt; that is made up of T(ranscript?) blocks of one or more sentences each. I'm guessing XCES doesn't support this kind of 3-tier structure, hence the ad-hoc markup, but as a long-time user of XML, I really would have preferred something like this:

&lt;pre class="brush: xml"&gt;
&lt;t id="T516" start="00:35:20,209" end="00:35:21,562"&gt;
  &lt;s id="733"&gt;
    &lt;w id="733.1"&gt;Get&lt;/w&gt;
    &lt;w id="733.2"&gt;down&lt;/w&gt;
    &lt;w id="733.3"&gt;,&lt;/w&gt;
    &lt;w id="733.4"&gt;guys&lt;/w&gt;
    &lt;w id="733.5"&gt;.&lt;/w&gt;
  &lt;/s&gt;
  &lt;s id="734"&gt;
    &lt;w id="734.1"&gt;Get&lt;/w&gt;
    &lt;w id="734.2"&gt;down&lt;/w&gt;
    &lt;w id="734.3"&gt;.&lt;/w&gt;
  &lt;/s&gt;
&lt;/t&gt;
&lt;/pre&gt;

&lt;p&gt;But, beggars can't be choosers, and anyway, my parser isn't a pure-XSLT solution anyway, so in the long run it doesn't matter all that much, even if it &lt;em&gt;does&lt;/em&gt; make the data purist in me cringe a little.&lt;/p&gt;

&lt;h4&gt;Shadow data&lt;/h4&gt;

&lt;p&gt;As the title of this post asserts, it's been my experience that data transformations are only rarely as straightforward as they look. Several years ago, I worked for a B2B e-commerce company that handled a lot of &lt;a href="en.wikipedia.org/wiki/Electronic_Data_Interchange" title="Electronic Data Interchange"&gt;EDI&lt;/a&gt; data, both reading it and writing it. In theory, this should be a &lt;em&gt;standard&lt;/em&gt; format: if you know the specification, you know what the data will look like. In practice, however, we found that every new company we brought on the system had their own "shadow" data structures hidden in the standard fields, just like the invisible &lt;code&gt;&amp;lt;t&amp;gt;ranscript&lt;/code&gt; blocks in this XCES data.&lt;/p&gt;

&lt;p&gt;The takeaway is this: when you're writing a parser for a new-to-you data format, no matter how "standard" it professes to be, never take your data's structure at face value. There may be hidden complexities, just waiting to be tripped over.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-297232520352433497?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/297232520352433497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/why-data-transformations-are-hard-part.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/297232520352433497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/297232520352433497'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/02/why-data-transformations-are-hard-part.html' title='Why data transformations are hard (part 2)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8783145334356955878</id><published>2010-01-25T09:33:00.001-05:00</published><updated>2010-08-04T23:45:21.312-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='EFR'/><category scheme='http://www.blogger.com/atom/ns#' term='VB'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><title type='text'>Why data transformations are hard (part 1)</title><content type='html'>&lt;p&gt;Per my &lt;a href="http://buyog.com/2010/01/so-as-i-mentioned-few-weeks-ago.html"&gt;plan for January&lt;/a&gt;, last Friday was the day I'd planned to have several &lt;a href="http://buyog.com/code/labels/EFR.html"&gt;&lt;abbr title="Electronic Film Review"&gt;EFR&lt;/abbr&gt;&lt;/a&gt; segmentation files ready for use later on in testing the software I'm going to build for my Linguistics MA capstone project.&lt;/p&gt;

&lt;p&gt;My task for that week was to take several XML movie transcripts (in segmented, time-aligned &lt;a href="http://www.xces.org/"&gt;XCES&lt;/a&gt; format) and spit out text files in a rather simple format I'll call EFR-segmentation (or &lt;var&gt;segfile&lt;/var&gt; for short), which can be parsed by other pre-existing tools in the EFR toolchain. Here's a sample of the input and target formats, so we can clearly define our start and end points:&lt;/p&gt;

&lt;strong&gt;XCES format (the source):&lt;/strong&gt;&lt;pre class="brush: xml"&gt;
  &lt;s id="20"&gt;
    &lt;time id="T14S" value="00:01:20,664" /&gt;
    &lt;w id="20.1"&gt;So&lt;/w&gt;
    &lt;w id="20.2"&gt;,&lt;/w&gt;
    &lt;w id="20.3"&gt;you&lt;/w&gt;
    &lt;w id="20.4"&gt;do&lt;/w&gt;
    &lt;w id="20.5"&gt;like&lt;/w&gt;
    &lt;w id="20.6"&gt;it&lt;/w&gt;
    &lt;w id="20.7"&gt;,&lt;/w&gt;
    &lt;w id="20.8"&gt;don'&lt;/w&gt;
    &lt;w id="20.9"&gt;t&lt;/w&gt;
    &lt;w id="20.10"&gt;you&lt;/w&gt;
    &lt;w id="20.11"&gt;?&lt;/w&gt;
    &lt;time id="T14E" value="00:01:22,332" /&gt;
  &lt;/s&gt;
&lt;/pre&gt;

&lt;strong&gt;EFR-segfile format (the target):&lt;/strong&gt;&lt;pre class="brush: text"&gt;
2460-2520 (00:01:20:20 - 00:01:22:11)
Scene 20: T14S
//T: So, you do like it, don't you?
&lt;/pre&gt;

&lt;p&gt;Since the starting point was an XML format, my first thought was to use XSLT transformations to accomplish the reformatting. I created a stylesheet, &lt;a href="http://buyog.com./files/segfile.xsl"&gt;segfile.xsl&lt;/a&gt;, to transform the XCES data files into something closely resembling the EFR-segfile format... but it was lacking in a couple of minor-but-not-insignificant ways. Observe:&lt;/p&gt;

&lt;strong&gt;Almost-but-not-quite-segfile format:&lt;/strong&gt;&lt;pre class="brush: text"&gt;
00:01:20,664
Scene 20: T14S
//T: So , you do like it , don' t you ?
&lt;/pre&gt;

&lt;p&gt;The major problem with this output is the timestamp, which in XCES is formatted like &lt;code&gt;hh:mm:ss,ms&lt;/code&gt;. EFR-segfile's timestamp format, on the other hand, is &lt;code&gt;start_frame-end_frame (hh:mm:ss:frame - hh:mm:ss:frame)&lt;/code&gt;. The milliseconds-to-frames part is easy:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
var old_format = "00:02:36,532";
var parts = old_format.split(',');
// X ms * (1 sec/1000 ms) * (30 frames/1 sec) = Y frames
var new_format = parts[0] + ':' + Math.round(parseInt(parts[1]) * 0.03);
// new_format == "00:02:36:16"
&lt;/pre&gt;

&lt;p&gt;... but the rest of that format change is &lt;strong&gt;not&lt;/strong&gt; so simple. We're lucky in the above segment, because there are two timestamps: one at the beginning and one at the end. This seems to be the exception, however, and not the rule, so we'll still need to keep some kind of "current timecode" variable on hand while our parser works its way through the file. Once this is addressed, a second task is to convert the segment start and end times from the &lt;code&gt;hh:mm:ss:ff&lt;/code&gt; format into raw frame counts, since EFR segfiles require both in order to have a valid timestamp line. This is a simple enough calculation, but again, doing it in XSLT is like trying to cut a 2x4 with a hammer, when we have other tools in our toolbox.&lt;/p&gt;

&lt;p&gt;Besides the timestamp-formatting issues, there was another glitch: the punctuation characters in the transcript line spit out by the XSLT are padded by unnecessary whitespace. For sentence terminators and splicers (periods, commas, etc), this doesn't present a huge problem. But inter-word apostrophes, indicating contractions, split up a word in such a way that any downstream term lookup routine will fail to match it properly. This kind of minor text cleanup would be a snap with my &lt;a href="http://buyog.com/code/downloads.php#Batleth"&gt;Bat'leth&lt;/a&gt; tool; it's designed with text parsing in mind, and has a lot of flexibility. But unfortunately, the timestamp conversion is more complex than Bat'leth's search-and-replace regular expressions can handle, so even if I used it for transcript cleanup, I'd still need another tool to do the timestamps.&lt;/p&gt;

&lt;p&gt;Given these shortcomings, I ruled out both XSLT and Bat'Leth as monolithic solutions, although each could contribute a step to the overall parsing workflow. I really wanted to have a single piece of software that could do both parts, however, so I decided to try doing it in Javascript. Then, I fell down the hole that is cross-browser XML &amp;mdash; which is a whole different blog post I'll have to write soon. (executive summary in one word: &lt;em&gt;complicated&lt;/em&gt;). Given the difficulty of that approach and the pressing deadline, I ended up &lt;a href="http://buyog.com/code/2010/01/view-source-is-good.html"&gt;writing something quick and dirty&lt;/a&gt; in Visual Basic 6. Not my first choice, but it got the job done.&lt;/p&gt;

&lt;p&gt;The story doesn't end there, though. One of the movies I wanted to treat was 1985's &lt;a href="http://www.imdb.com/title/tt0089218/"&gt;The Goonies&lt;/a&gt;, something of a cultural touchstone for my generation. I found an &lt;a href="http://buyog.net/files/4759_137270_188200_the_goonies.xml.gz"&gt;XCES alignment file&lt;/a&gt; for the movie in the 
&lt;a href="http://urd.let.rug.nl/tiedeman/OPUS/OpenSubtitles.php"&gt;OPUS OpenSubtitles&lt;/a&gt; corpus that I'm using, fed it through my parser, and got &lt;a href="http://buyog.net/files/goonies__seg.txt"&gt;this EFR-segfile&lt;/a&gt;. Looked pretty good, I thought... so I fired up my &lt;a href="http://buyog.com/code/2008/09/electronic-film-reviews-customize-your.html"&gt;EFR authoring software&lt;/a&gt; to verify the transcript alignment. And.... it didn't match up! Tune in later this week for part 2 of this post, when we try to figure out why.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8783145334356955878?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8783145334356955878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/why-data-transformations-are-hard-part.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8783145334356955878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8783145334356955878'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/why-data-transformations-are-hard-part.html' title='Why data transformations are hard (part 1)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-732600074118743148</id><published>2010-01-17T21:44:00.003-05:00</published><updated>2010-01-17T22:04:30.378-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='VB'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Updated download: Bat'leth 3.1</title><content type='html'>&lt;p&gt;This weekend I've been working with &lt;a href="http://buyog.com/code/downloads.php#Batleth"&gt;Bat'leth&lt;/a&gt;, a tool I wrote a number of years ago for text processing and data format manipulation, on a project for my Computational Linguistics graduate work that I'll be blogging about soon. As I worked with it, I noticed that it was looking quite &lt;em&gt;dated&lt;/em&gt;. It didn't support XP-style controls, some of the button images were inconsistently styled and not properly masked, and so forth. (I also found a bug or two!)&lt;/p&gt;

&lt;p&gt;As I wrote &lt;a href="http://buyog.com/code/2010/01/dear-visual-basic-its-not-you-its-me.html"&gt;a few days ago&lt;/a&gt;, I have a love/hate relationship with my old Visual Basic code: I love how easy it is to hack together a "quick and dirty" tool when I need one, and I hate how hard it is to make it actually look polished and modern when finished. Then I stumbled across an add-on for VB called &lt;a href="http://vb.mvps.org/tools/vbAdvance/"&gt;vbAdvance&lt;/a&gt;. It extends old-school VB in some very welcome ways, including the ability to compile an XP manifest file into your apps so that they support the newer visual styles (other cool features include the ability to create DLLs with function exports, console apps with no GUI, and several other nifty bits). Though originally commercial, it's now classed as "unsupported freeware," so if you or anyone you know does any work in classic VB, this is well worth your time.&lt;/p&gt;

&lt;p&gt;Anyway, thanks to vbAdvance and a little surplus time this weekend, I've updated Bat'leth to version 3.1, now available on &lt;a href="http://buyog.com/code/downloads.php#Batleth"&gt;my downloads page&lt;/a&gt; as both an install package and full VB6 source code. Enjoy, and let me know if you find this at all useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-732600074118743148?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/732600074118743148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/updated-download-batleth-31.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/732600074118743148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/732600074118743148'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/updated-download-batleth-31.html' title='Updated download: Bat&apos;leth 3.1'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5824227102770437725</id><published>2010-01-14T12:31:00.002-05:00</published><updated>2010-01-15T12:53:38.229-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VB'/><category scheme='http://www.blogger.com/atom/ns#' term='methodology'/><title type='text'>Dear Visual Basic: It's not you, it's me</title><content type='html'>&lt;p&gt;I just read a great article over at O'Reilly, &lt;a href="http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html"&gt;7 reasons I switched back to PHP after 2 years on Rails&lt;/a&gt;. It's a few years old, and the comments thread is practically a flamewar between pro- and anti- Ruby on Rails people, but the article itself raises some great points &amp;mdash; not about how awesome PHP is, but about the art and science of software design. The author, Derek Sivers (founder of &lt;a href="http://www.cdbaby.com/"&gt;CD Baby&lt;/a&gt;) had this to say about a developer's perennial urge to rewrite old code:&lt;/p&gt;

&lt;blockquote&gt;But the main reason that any programmer learning any new language thinks the new language is SO much better than the old one is because he’s a better programmer now! You look back at your old ugly PHP code, compared to your new beautiful Ruby code, and think, &amp;quot;God that PHP is ugly!&amp;quot; But don’t forget you wrote that PHP years ago and are unfairly discriminating against it now.
It’s not the language (entirely). It’s you, dude. You’re better now. Give yourself some credit.&lt;/blockquote&gt;

&lt;p&gt;I love that! This week I've been re-visiting a lot of my old Visual Basic code to get some things &lt;a href="http://buyog.com/code/2010/01/downloads-now-with-source-code.html"&gt;freshened up&lt;/a&gt; for my Downloads page, so I can absolutely relate. Looking over the code, it's easy to dismiss it as simplistic and over-reliant on hacks to accomplish its aims. So Sivers' article was a nice reminder to me that the language itself isn't the problem (well, mostly), it's just the way I wrote in it. So if time allows, I'll be revisiting a few of these tools in the coming weeks with an eye to make them better.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5824227102770437725?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5824227102770437725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/dear-visual-basic-its-not-you-its-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5824227102770437725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5824227102770437725'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/dear-visual-basic-its-not-you-its-me.html' title='Dear Visual Basic: It&apos;s not you, it&apos;s me'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7355643456383348724</id><published>2010-01-13T19:58:00.002-05:00</published><updated>2010-01-13T20:07:49.139-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='VB'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Downloads: now with source code</title><content type='html'>&lt;p&gt;I've fixed the &lt;a href="http://buyog.com/code/2010/01/broken-downloads.html"&gt;broken links&lt;/a&gt; on my &lt;a href="http://buyog.com/code/downloads.php"&gt;Downloads&lt;/a&gt; page. So far there are mostly only zip archives with the VB6 source code, with only one app that actually includes an installer. I intend to upload more binaries and/or installers soon; tonight I'm working on an update to &lt;a href="http://buyog.com/code/downloads.php#Batleth"&gt;Bat'leth&lt;/a&gt; that will help me do some work on my grad school project (I'll post more on that effort on my &lt;a href="http://buyog.com"&gt;root blog&lt;/a&gt; in a day or two)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7355643456383348724?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7355643456383348724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/downloads-now-with-source-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7355643456383348724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7355643456383348724'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/downloads-now-with-source-code.html' title='Downloads: now with source code'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6346289777651333012</id><published>2010-01-13T07:47:00.004-05:00</published><updated>2010-01-13T07:53:51.620-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Broken downloads</title><content type='html'>So &lt;a href="http://buyog.com/code/2010/01/minor-update.html"&gt;a few days ago&lt;/a&gt; I posted an update, in which I discussed moving the ancillary pages here on the site to PHP. Part of that update included a link in the titlebar to a refreshed version of my &lt;a href="http://buyog.com/code/downloads.php"&gt;Downloads&lt;/a&gt; page, which includes a handful of tools of various levels of usefulness I've built over the years. Well, apparently I made the changes too late at night or too early in the morning, because I forgot to update the links to the actual downloads themselves! I'm at work now and can't access my FTP server, but I'll make the necessary changes tonight so that anyone who wants to download my tools... can actually do so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6346289777651333012?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6346289777651333012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/broken-downloads.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6346289777651333012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6346289777651333012'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/broken-downloads.html' title='Broken downloads'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-668916253959648178</id><published>2010-01-11T23:16:00.004-05:00</published><updated>2010-01-11T23:45:25.564-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Minor update</title><content type='html'>&lt;p&gt;Just like I did with my &lt;a href="http://buyog.com/MUGEN/2010/01/finished-tweaking.html"&gt;MUGEN blog&lt;/a&gt; a few days ago, I've updated this site to use PHP instead of static HTML pages. Not a huge thing, but at least now the site's subsections (currently &lt;a href="http://buyog.com/code/loc.php"&gt;Canvassa&lt;/a&gt; and &lt;a href="http://buyog.com/code/downloads.php"&gt;Downloads&lt;/a&gt;) have a prominent location in the toolbar, and all pages on the site (except the blog index, since Blogger can't generate PHP) can reuse the same header/sidebar/footer resources.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-668916253959648178?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/668916253959648178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/minor-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/668916253959648178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/668916253959648178'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/minor-update.html' title='Minor update'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6753978448014450765</id><published>2010-01-08T09:48:00.005-05:00</published><updated>2010-01-08T10:58:39.526-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='VB'/><category scheme='http://www.blogger.com/atom/ns#' term='methodology'/><title type='text'>View-Source is Good?</title><content type='html'>&lt;p&gt;Alex Russell, founder and president of the Dojo Foundation, recently wrote on his blog about the &lt;a href="http://alex.dojotoolkit.org/2010/01/view-source-is-good-discuss/"&gt;importance of "view source"&lt;/a&gt; to the evolution and growth of the World Wide Web:&lt;/p&gt;&lt;blockquote&gt;Web developers get started by taking some code, pasting it into a file, loading it in a browser and switching between editor and browser between even the most minor changes. This is a stark contrast with other types of development, notably those that impose a compilation step on development, in which the process of seeing what what done requires an intermediate action. In other words, immediacy of output helps build an understanding of how the system will behave, and ctrl-r becomes a seductive and productive way for developers to accelerate their learning in the copy-paste-tweak loop. The only required equipment is a text editor and a web browser, tools that are free and work together instantly. That is to say, there’s no waiting between when you save the file to disk and when you can view the results. It’s just a ctrl-r away.&lt;/blockquote&gt;&lt;p&gt;As I read the above quote, it hit me: this is &lt;em&gt;exactly&lt;/em&gt; why I love developing in old-school Visual Basic, and why even now VB.NET doesn't feel natural to me. For almost 10 years, my work was primarily done in Visual Basic 5 (and later 6), where the normal process of development runs something like:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Design something in the UI&lt;/li&gt;&lt;li&gt;Write an event handlers for the UI component&lt;/li&gt;&lt;li&gt;Run the app in debug mode and test the new feature&lt;/li&gt;&lt;li&gt;Break program execution and tweak the event handler&lt;/li&gt;&lt;li&gt;Continue program execution and test the revised code&lt;/li&gt;&lt;li&gt;Repeat steps 1-5 as necessary&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This is precisely the same reason why I love web development so much: the immediacy of the feedback loop, the ability to see your changes almost as you make them, and to, essentially, &lt;em&gt;evolve&lt;/em&gt; the code to achieve your end goals. Tools like &lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt; have made this process even easier, allowing me to actually poke and prod UI elements in runtime without having to change and refresh the underlying code. And I absolutely love the ability to see a &lt;a href="http://www.pahk.de/jsconf/"&gt;cool&lt;/a&gt; &lt;a href="http://hernan.amiune.com/labs/particle-system/hello-world.html"&gt;effect&lt;/a&gt; &lt;a href="http://blog.nihilogic.dk/2009/10/strange-attractors-beautiful-chaos-and.html"&gt;coded&lt;/a&gt; by someone else, and do the old "right-click, inspect element" to see how they did it.&lt;/p&gt;&lt;p&gt;Interestingly, the parallels between VB and the web don't end there. From time to time you hear developers of languages like Java and C++ pooh-pooh both Visual Basic and Javascript as being somehow "&lt;a href="http://stackoverflow.com/questions/720228/why-are-vb-net-programmers-looked-down-upon"&gt;inferior&lt;/a&gt;". The simple syntax, lack of a compiler and need for a runtime are somehow seen as negatives, even though the trend from the beginning has always been towards &lt;em&gt;more&lt;/em&gt;, not less, abstraction.&lt;/p&gt;&lt;p&gt;Now, do I use VB6 for all of my Windows desktop development? No, I also code in C++, C#, and sometimes even batch scripts. Do I use JavaScript for all of my web development? No, all of my back-end and template code is typically written in Python, PHP, and the like. But for when I need a &lt;a href="http://buyog.com/MUGEN/2010/01/on-13th-day-of-christmas.html"&gt;simple tool&lt;/a&gt; to do a simple job, simple code wins every time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6753978448014450765?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6753978448014450765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/view-source-is-good.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6753978448014450765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6753978448014450765'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/view-source-is-good.html' title='View-Source is Good?'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1299183837003131786</id><published>2010-01-01T17:31:00.003-05:00</published><updated>2010-01-01T17:36:33.502-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Happy Birthday, Canvassa</title><content type='html'>&lt;p&gt;I just realized it's been a year since &lt;a href="http://buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html"&gt;my first post&lt;/a&gt; detailing my efforts to re-create The NES Legend of Zelda in Javascript and HTML5/Canvas. I'm currently on hiatus, &lt;a href="http://buyog.com/2009/12/home-from-hospital.html"&gt;recuperating from minor sinus surgery&lt;/a&gt; earlier in the week, but I have an update in mind for later this month.&lt;/p&gt;
&lt;p&gt;Until then, enjoy the current version &lt;a href="http://buyog.com/code/loc/Canvassa/"&gt;here&lt;/a&gt;, and have a happy 2010.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1299183837003131786?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1299183837003131786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/happy-birthday-canvassa.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1299183837003131786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1299183837003131786'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2010/01/happy-birthday-canvassa.html' title='Happy Birthday, Canvassa'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8878381012070430348</id><published>2009-12-24T08:56:00.002-05:00</published><updated>2009-12-24T09:01:24.560-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Harmful Changes (and a Christmas Miracle)</title><content type='html'>&lt;p&gt;&lt;a href="http://buyog.com/code/2009/12/cloning-zelda-harmless-animations.html"&gt;Yesterday's post&lt;/a&gt;, which I called "Harmless Animations", led to me making a stupid &amp;ndash; and &lt;em&gt;harmful&lt;/em&gt; &amp;ndash; change that I should have known better. It's worth talking about what happened, and why.&lt;/p&gt;

&lt;p&gt;When I first implemented the &lt;var&gt;loc.Explod&lt;/var&gt; class and the four SwordFlash elements, this is what the code that added them to the game screen looked like:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
terminate: function swordProj_terminate() {
    game.insertProjectile(new loc.SwordFlashNW({'pos':this.getPos(),'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSW({'pos':this.getPos(),'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashNE({'pos':this.getPos(),'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSE({'pos':this.getPos(),'owner':this.owner}));

    this.inherited(arguments);
}
&lt;/pre&gt;

&lt;p&gt;When I was blogging about the new code yesterday, I "streamlined" that function a bit to look like this:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
terminate: function swordProj_terminate() {
    var myPos = this.getPos();
    game.insertProjectile(new loc.SwordFlashNW({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSW({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashNE({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSE({'pos':myPos,'owner':this.owner}));

    this.inherited(arguments);
}
&lt;/pre&gt;

&lt;p&gt;Do you see what I broke? It's probably not at all obvious... it certainly wasn't to me. I thought that I was &lt;em&gt;optimizing&lt;/em&gt; the code by only running &lt;code&gt;getPos()&lt;/code&gt; once and passing its value to all four child explods. But last night, I went to change the live code to reflect the blog post, in case anyone wanted to examine the new bits in context. When I did so, my sword flashes stopped behaving right! If the sword hit a monster, all four explods sat still in the exact spot where they were inserted, and if the sword made it to the end of the screen, two of them would come straight back, rather than at their proper angles. What the heck did I &lt;em&gt;do&lt;/em&gt;?!?&lt;/p&gt;

&lt;p&gt;I really should have known better, since this has tripped me up before. To explain what the difference is in these two code blocks, you need to know what the &lt;code&gt;getPos()&lt;/code&gt; method (which is inherited from &lt;var&gt;loc.Sprite&lt;/var&gt;) actually does:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
getPos: function sprite_pos() {
    return dojo.clone(this.pos);
}
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;&lt;a href="http://docs.dojocampus.org/dojo/clone"&gt;dojo.clone()&lt;/a&gt;&lt;/code&gt; is a cool little function. In a nutshell, it creates &lt;a href="http://en.wikipedia.org/wiki/Object_copy#Deep_copy"&gt;deep copies&lt;/a&gt; of JavaScript objects, which is &lt;em&gt;tremendously&lt;/em&gt; useful if you want something approximating a &lt;code&gt;struct&lt;/code&gt; datatype. This is exactly how I'm doing (x,y) pairs in Canvassa, which I use for both sprite position and velocity:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
dojo.declare("loc.Sprite", null, {
    pos: {x:0, y:0},
    vector: {x:0,y:0},
...
})
&lt;/pre&gt;

&lt;p&gt;The problem comes when you try to reuse one of these position values, which is precisely what the second code block tried to do, and is precisely why I created the &lt;code&gt;getPos()&lt;/code&gt; method in the first place! Since a sprite's position is an object and not a struct, I need to &lt;code&gt;dojo.clone()&lt;/code&gt; it to get a copy of its contained values instead of a copy of its pointer reference (see &lt;a href="http://snook.ca/archives/javascript/javascript_pass"&gt;Jonathan Snook's explanation&lt;/a&gt; of why JavaScript works this way). Now, I'm not a n00b programmer. I've been around the block a few times, and have coded in nearly a dozen different languages in my time, and in many of them I was well aware of this Pass-by-Reference/Pass-by-Value distinction. And yet, in an effort to clean up my code, I managed to instantiate four separate SwordFlash explods and give all four of them &lt;em&gt;the same position object!&lt;/em&gt; So when the game told them to update their positions, each in turn would modify its position object relative to its personal velocity:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
// let's assume the starting position is {x:32, y:64}

// in SwordFlashNW.updatePosition():
this.pos.x += -3;  // {x:29, y:64}
this.pos.y += -3;  // {x:29, y:61}

// SwordFlashSW.updatePosition():
this.pos.x += -3;  // {x:26, y:61}
this.pos.y += 3;  // {x:26, y:64}

// SwordFlashNE.updatePosition():
this.pos.x += 3;  // {x:29, y:64}
this.pos.y += -3;  // {x:29, y:61}

// SwordFlashSE.updatePosition():
this.pos.x += 3;  // {x:32, y:61}
this.pos.y += 3;  // {x:32, y:64}

// end position for all four: {x:32, y:64}
&lt;/pre&gt;

&lt;p&gt;So when all four explods were operating on a single, shared position object, the net result was no movement at all! And when, in the edge case, two of the explods went off the screen and were removed, the other two combined forces to push the position in a single direction. D'OH!&lt;/p&gt;

&lt;p&gt;So, hopefully this time I've learned the lesson well enough that it'll sink in: my sprites' &lt;code&gt;pos&lt;/code&gt; and &lt;code&gt;vector&lt;/code&gt; values are objects, and I need to call &lt;code&gt;getPos()&lt;/code&gt; &lt;em&gt;EVERY&lt;/em&gt; time I want a non-interfering copy. Sure, it's not as profound a December lesson as "&lt;cite&gt;&lt;a href="http://www.gutenberg.org/files/46/46-h/46-h.htm"&gt;I will honour Christmas in my heart, and try to keep it all the year&lt;/a&gt;&lt;/cite&gt;," but it'll do.&lt;/p&gt;

&lt;p&gt;Happy Christmas to all, and to all a good night!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8878381012070430348?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8878381012070430348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-harmful-changes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8878381012070430348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8878381012070430348'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-harmful-changes.html' title='Cloning Zelda: Harmful Changes (and a Christmas Miracle)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8345220463453632607</id><published>2009-12-23T12:41:00.002-05:00</published><updated>2009-12-23T22:44:08.417-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='MUGEN'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Harmless Animations</title><content type='html'>&lt;img src="http://buyog.com/code/images/loc_explod.png" alt="flashing shards fly off an octoroc when Link kills it with his sword"/&gt;&lt;p&gt;So.&lt;/p&gt;&lt;p&gt;Long time no &lt;a href="http://buyog.com/code/2009/12/cloning-zelda-and-lo-there-came-archive.html"&gt;update&lt;/a&gt;, eh? (at least, it's been a while since a &lt;a href="http://buyog.com/code/2009/10/cloning-zelda-adding-title-screen.html"&gt;&lt;em&gt;substantial&lt;/em&gt;&lt;/a&gt; update)&lt;/p&gt;

&lt;p&gt;A few weeks ago, I added something new and kinda cool to &lt;a href="http://buyog.com/code/loc/Canvassa/"&gt;Canvassa&lt;/a&gt;. We've had sword projectiles for a while now, but it felt like something was missing... in the original game, when a thrown sword hits an enemy or a wall, you get this cool effect that the above screenshot shows off: a handful of flashing shards that fly off in 4 different directions. I'd been missing these, and wanted to add them to Canvassa, but I was afraid I had a "painted into a corner" situation on my hands: the game engine I'd built up so far had a couple of different types of sprites it handles, and the sword shards don't really fit any of them:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;Player&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: player main sprites&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: user-controlled&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can be hurt if touched by a monster or projectile&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Monsters&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: octorocs, tectites, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: autonomous (via &lt;abbr title="artificial intelligence"&gt;AI&lt;/abbr&gt;)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can be hurt if hit by player's weapon or projectile&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Items&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: small hearts, rupees, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: none (except for fairies)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can be picked up if touched&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Projectiles&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: throwing sword, octoroc rocks, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: pre-determined&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can do damage if it touches a player or monster&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Sword shards don't neatly fit into any of these boxes: they aren't controlled by the player or an AI, and while they &lt;em&gt;do&lt;/em&gt; move in a predetermined way and can't be picked up (like projectiles), they don't hit obstacles or do damage to anything the way projectiles do.&lt;/p&gt;

&lt;p&gt;As I mulled over the problem of how to implement these shards, inspiration struck: the MUGEN &lt;em&gt;&lt;a href="http://elecbyte.com/wiki/index.php/Explod"&gt;Explod&lt;/a&gt;&lt;/em&gt; construct! For the past several years I've developed something of a &lt;a href="http://buyog.com/MUGEN"&gt;name&lt;/a&gt; for myself as a programmer (and occasional graphic artist) of &lt;a href="http://buyog.com/MUGEN/charsel.html"&gt;custom characters&lt;/a&gt; for the open &lt;a href="http://en.wikipedia.org/wiki/M.U.G.E.N"&gt;MUGEN&lt;/a&gt; fighting game engine. In my time working with that programming model, I've become familiar with its 4 tiers of sprite object hierarchy:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Player&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: the character's core sprites&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: user-controlled&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can do damage and be damaged&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;a href="http://elecbyte.com/wiki/index.php/Helper"&gt;Helper&lt;/a&gt;&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: extensions of the character such as weapons, clones, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: user-controlled or autonomous&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can do damage and be damaged&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;a href="http://elecbyte.com/wiki/index.php/Projectile"&gt;Projectile&lt;/a&gt;&lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: things thrown/shot/expelled by the player&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: pre-determined&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: can do damage and be blocked (but not hurt, per se)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;a href="http://elecbyte.com/wiki/index.php/Explod"&gt;Explod&lt;/a&gt;&lt;/em&gt; (no, I didn't misspell it)&lt;ul&gt;&lt;li&gt;&lt;strong&gt;used for&lt;/strong&gt;: used for visual effects such as dust or hit sparks&lt;/li&gt;&lt;li&gt;&lt;strong&gt;movement&lt;/strong&gt;: pre-determined&lt;/li&gt;&lt;li&gt;&lt;strong&gt;attributes&lt;/strong&gt;: cannot do damage or be damaged&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The above 4-way distinction between MUGEN sprite types seems to map pretty well to the engine I'm building, and it's a metaphor I'm familiar with, so I determined to apply it. For my purposes, Explods act almost exactly like Projectiles, except for two things: they don't do damage to anyone (or anything), and they have a time limit, after which they get removed from the screen. So the simplest thing to do is to subclass the &lt;var&gt;loc.Projectile&lt;/var&gt; class and override the default behavior for these two differences:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
dojo.declare("loc.Explod", loc.Projectile, {
    timeout: -1,
    constructor: function(args){
        /* required args: 'pos' and 'owner' (inherited from Projectile)
           optional args: 'timeout' (defaults to -1, meaning it never gets removed) and 'vel' (movement velocity) */
        dojo.mixin(this, args);
    },
    hit: function explod_hit() {
        // do nothing when making contact with another sprite
    },
    updatePosition: function() {
        if (this.timeout-- == 0) {
            this.terminate();   // when timeout runs down, tell the game to remove me
        }
        this.inherited(arguments);
    },
    _animateCurrent: function explod_animateCurrent() {
        return true;  // override default behavior to animate even if motionless
    }
});
&lt;/pre&gt;
&lt;a href="http://buyog.com/code/loc/Canvassa/loc/Item.js"&gt;View the code&lt;/a&gt;

&lt;p&gt;Simple, right? Now, when I need an Explod-type effect, I simply subclass &lt;var&gt;loc.Explod&lt;/var&gt; and add the necessary animation details. For the shattering sword, I defined four &lt;var&gt;SwordFlash&lt;/var&gt; subclasses, one for each of the four shards created when a &lt;var&gt;SwordProj&lt;/var&gt; projectile is terminated (&lt;abbr title="NorthWest"&gt;NW&lt;/abbr&gt;, &lt;abbr title="SouthWest"&gt;SW&lt;/abbr&gt;, &lt;abbr title="NorthEast"&gt;NE&lt;/abbr&gt;, and &lt;abbr title="SouthEast"&gt;SE&lt;/abbr&gt;, for the direction they move). In each, I specified the initial velocity and timeout values to be used (though I could also specify these during object instantiation, if I wanted to override the defaults):&lt;/p&gt;

&lt;pre class="brush: js"&gt;
dojo.declare("loc.SwordFlashNW", loc.Explod, {
    constructor: function(args){
        dojo.mixin(this, args);
        this.width = 8; this.height = 10;
        this.vel = {x: -3, y: -3}; this.timeout = 10;
        this._stateDefs = [ { faceted:false, nextState: 0, canMove: true,
            anim: [ [{x:152,y:11,t:1},{x:160,y:11,t:1}] ] }];
    }
});
&lt;/pre&gt;
&lt;a href="http://buyog.com/code/loc/Canvassa/loc/Item.js"&gt;View the code&lt;/a&gt;

&lt;p&gt;With these four classes now defined, all I had to do was add a custom &lt;code&gt;terminate()&lt;/code&gt; function to the &lt;var&gt;loc.SwordProj&lt;/var&gt; "throwing sword" class, using it to insert a new instance of each explod into &lt;var&gt;game.projectiles&lt;/var&gt;:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
terminate: function swordProj_terminate() {
    var myPos = this.getPos();
    game.insertProjectile(new loc.SwordFlashNW({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSW({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashNE({'pos':myPos,'owner':this.owner}));
    game.insertProjectile(new loc.SwordFlashSE({'pos':myPos,'owner':this.owner}));

    this.inherited(arguments);
}
&lt;/pre&gt;
&lt;a href="http://buyog.com/code/loc/Canvassa/loc/Item.js"&gt;View the code&lt;/a&gt;

&lt;p&gt;You can see the results &lt;a href="http://buyog.com/code/loc/Canvassa"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you clicked the above link and tested out the new feature, one thing you likely noticed is that the sword only works if you have full health; get touched by a monster, and suddenly you can't attack anymore... lame! Next time, we'll look at how the MUGEN &lt;em&gt;&lt;a href="http://elecbyte.com/wiki/index.php/Helper"&gt;Helper&lt;/a&gt;&lt;/em&gt; construct can help us fix this problem.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8345220463453632607?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8345220463453632607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-harmless-animations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8345220463453632607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8345220463453632607'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-harmless-animations.html' title='Cloning Zelda: Harmless Animations'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1015658272885850047</id><published>2009-12-03T12:08:00.006-05:00</published><updated>2010-01-11T23:44:00.253-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Blogger is Busted (or, Hacking your Template to Eliminate the "a[...] is null or not an object" Error)</title><content type='html'>&lt;p&gt;Earlier this morning, I posted &lt;a href="http://buyog.com/code/2009/12/blogger-backlinks_03.html"&gt;a quick test&lt;/a&gt; to see if backlinks are working with Blogger-powered blogs posting to FTP, as I'm doing. Turns out that &lt;a href="http://buyog.com/code/2009/12/cloning-zelda-and-lo-there-came-archive.html"&gt;they're not&lt;/a&gt; (note the absence of backlinkage on that page &lt;em&gt;I just linked to&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Now, this isn't a huge problem for me. Would I like the ego-stroking that comes with having backlinks, showing that people like what I'm doing enough to share it? Well, sure I would. But is it worth the pain and hassle? No. So I went into my blogger settings panel, and disabled all the bits pertaining to backlinks, and removed the backlink scripts from my custom template.&lt;/p&gt;

&lt;p&gt;Unsurprisingly, this didn't solve the underlying problem -- my site was throwing JavaScript errors! I already knew what was causing the errors: as I said in my &lt;a href="http://buyog.com/code/2009/12/blogger-backlinks_03.html"&gt;previous post&lt;/a&gt;, Blogger is auto-inserting some invalid-in-my-context JS code after every post, precisely where the &amp;lt;/Blogger&amp;gt; tag lies in my template. Searching around a bit more, I found a solution &lt;a href="http://www.google.com/support/forum/p/blogger/thread?tid=36c362c289aa5724&amp;hl=en"&gt;at Google's Blogger support forum&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;blockquote&gt;Kham
Level 1
8/29/09
This has done the trick for me.

Wrap all instances of &amp;lt;blogger&amp;gt; and &amp;lt;/blogger&amp;gt; with both the HTML and JavaScript comments.
&amp;lt;!--/* &amp;lt;Blogger&amp;gt; */ --&amp;gt;
&amp;lt;!--/* &amp;lt;/Blogger&amp;gt; */ --&amp;gt;
&lt;/blockquote&gt;&lt;/pre&gt;

&lt;p&gt;Stupid, stupid, stupid! Since I can't get Blogger to stop inserting the offending code, I have to force it to be commented out! Maybe it's time to take another look at alternative blog engines...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1015658272885850047?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1015658272885850047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/blogger-is-busted.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1015658272885850047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1015658272885850047'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/blogger-is-busted.html' title='Blogger is Busted (or, Hacking your Template to Eliminate the &quot;a[...] is null or not an object&quot; Error)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5630541662612740734</id><published>2009-12-03T11:17:00.004-05:00</published><updated>2010-01-11T23:44:00.253-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Blogger Backlinks</title><content type='html'>&lt;p&gt;The following link is to my previous post; I'm testing to see if that post recognizes it as a valid backlink: &lt;a href="http://buyog.com/code/2009/12/cloning-zelda-and-lo-there-came-archive.html#links"&gt;Palagpat Coding: Cloning Zelda: And Lo, There Came... an Archive!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A little background: I publish via Blogger's "post to FTP" option, rather than using the apparently-more-kosher Blogspot hosting. Apparently, &lt;a href="http://www.webmasterworld.com/content_management/3942876.htm"&gt;in late June of this year&lt;/a&gt;, other bloggers doing the same thing began seeing mysterious blogs of javascript getting inserted into their published files, most frequently showing up in people's &amp;lt;title&amp;gt; tags, and thus in search results (&lt;a href="http://www.google.com/search?q=blogger+attachCsiOnload"&gt;see for yourself&lt;/a&gt; in a Google search for the offending string). If backlinks aren't actually functional in my blog configuration, then I'm going to try turning them off to see if it solves the problem.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5630541662612740734?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5630541662612740734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/blogger-backlinks_03.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5630541662612740734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5630541662612740734'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/blogger-backlinks_03.html' title='Blogger Backlinks'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2267504209882097537</id><published>2009-12-02T00:14:00.003-05:00</published><updated>2010-01-11T23:44:00.254-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Cloning Zelda: And Lo, There Came... an Archive!</title><content type='html'>&lt;p&gt;Short update tonight. Bullet points, because I love 'em so much:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;I've added a few pretty keen new tidbits to &lt;a href="/code/loc/Canvassa/"&gt;Canvassa&lt;/a&gt;, and will be blogging about them soon. &lt;/li&gt;&lt;li&gt;Speaking of Canvassa, I've revamped the &lt;a href="/code/loc/"&gt;Canvassa Archive&lt;/a&gt; page with a more up-to-date (and relevant) development roadmap, including links to all related blog posts on each finished task.&lt;/li&gt;&lt;li&gt;Updated and cleaned up the navigation toolbar; it should now degrade better for IE and mobile users.&lt;/li&gt;&lt;li&gt;New favicon / site logo. Whaddayathink?&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2267504209882097537?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2267504209882097537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-and-lo-there-came-archive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2267504209882097537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2267504209882097537'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/12/cloning-zelda-and-lo-there-came-archive.html' title='Cloning Zelda: And Lo, There Came... an Archive!'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-440429179383484376</id><published>2009-11-06T13:21:00.006-05:00</published><updated>2009-11-30T00:49:05.237-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Javascript Snippet: Flip Text Upside-down</title><content type='html'>&lt;script type="text/javascript" language="javascript"&gt;
  /*
  dojo.registerModulePath('plugd', '/code/misc/');
  dojo.require("plugd.flip");
  */
&lt;/script&gt;

&lt;p&gt;This week I was playing with my &lt;a href="http://www.google.com/analytics/" target="_blank"&gt;Google Analytics&lt;/a&gt; account to see what was happening with my blogs; it turns out that my &lt;a href="http://buyog.com/MUGEN" target="_blank"&gt;MUGEN blog&lt;/a&gt; is about a &lt;abbr title="(not a technical term)"&gt;bajillion&lt;/abbr&gt; times more popular than this one. Guess I'm learning, as &lt;a href="http://www.sheldoncomics.com/archive/091011.html" target="_blank"&gt;Arthur Conan Doyle did&lt;/a&gt;, that you don't get 
to pick what you're known for (sigh). That said, the most popular post here on the ol' Coding blog was &lt;a href="http://www.buyog.com/code/2009/06/simple-tag-cloud-generator-in.html" target="_blank"&gt;this one&lt;/a&gt;, where I talked about my home-grown tag cloud generator. So, although &lt;a href="http://buyog.com/code/loc" target="_blank"&gt;Canvassa&lt;/a&gt; isn't going to be dropped, I'm going to pepper in more of these "&lt;a href="http://buyog.com/code/labels/snippets.html" target="_blank"&gt;snippets&lt;/a&gt;" types of articles from time to time... like today!&lt;/p&gt;

&lt;p&gt;Back in April of this year, YouTube did an April Fool's joke where they turned their site upside-down by means of a sneaky little code snippet that swapped out all alphanumeric characters with characters that looked like upside-down versions of themselves (for example, 6 became 9, M became W, etc). Later, Paul Irish adapted the code into a &lt;a href="http://paulirish.com/2009/flip-text-upside-down-jquery-plugin/" target="_blank"&gt;jQuery plugin&lt;/a&gt;. Still later, I followed his lead and adapted the code as a &lt;a href="http://higginsforpresident.net/2009/05/more-on-dojo-plugins/" target="_blank"&gt;Dojo plugin&lt;/a&gt;, and &lt;a href="http://twitter.com/buyog/status/1879091830" target="_blank"&gt;posted it on Twitter&lt;/a&gt;. But I never blogged about it here.&lt;/p&gt;

&lt;p&gt;In fact, it's even been in one of my &lt;a href="http://github.com/buyog/MiscJS" target="_blank"&gt;Github repositories&lt;/a&gt; for months now, completely undocumented save its internal code comments. Surprise!&lt;/p&gt;

&lt;p&gt;&lt;a href="#" onClick="javascript:var q=dojo.query('div.post');q.flip();return false;"&gt;Click here&lt;/a&gt; to flip all the posts on this page, re-arranging them from top to bottom, or &lt;a href="#" onClick="javascript:var q=dojo.query('h1, h2, h3, p, code, blockquote, pre, a, option, td, dd, li');q.flip();return false;"&gt;click here&lt;/a&gt; to flip their text in place without moving it around.&lt;/p&gt;

&lt;p&gt;I wanted to go back re-implement the code as a bookmarklet, but it's currently dependent on (and namespaced in) Dojo, so that didn't get done. Maybe for the next snippet.&lt;/p&gt;

&lt;p&gt;Oh, also of note: I've re-arranged my site template a bit, moving navigation from the sidebar to the header, adding more social networking links to my profile, and pushing it further down the sidebar. This is part of my effort to harmonize all three of my blogs into a single site, and there will likely be more changes before that effort is complete.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update, 11/30/2009&lt;/em&gt;: Some recent template changes to the blog have broken the dynamically-loaded code in this post; I'm working on a fix.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-440429179383484376?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/440429179383484376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/11/javascript-snippet-flip-text-upside.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/440429179383484376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/440429179383484376'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/11/javascript-snippet-flip-text-upside.html' title='Javascript Snippet: Flip Text Upside-down'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5304413750358956749</id><published>2009-10-26T08:25:00.003-05:00</published><updated>2009-10-26T08:44:16.214-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: 0.5.x</title><content type='html'>&lt;img src="http://buyog.com/code/loc/Canvassa/loc/res/select.png" alt="Zelda menu screen"/&gt;&lt;p&gt;I'm not exactly sure what release number this is, or if such things really even apply to an experimental web game I operate on "live." But anyway, I wanted to give a brief "State of &lt;a href="http://buyog.com/code/loc/Canvassa"&gt;Canvassa&lt;/a&gt;" update on my recent changes.&lt;/p&gt;&lt;p&gt;A couple of my recent changes are completed tasks from my &lt;a href="http://buyog.com/code/2009/09/canvassa-05-bug-list.html"&gt;recently posted&lt;/a&gt; bug list for version 0.5:&lt;/p&gt;&lt;ul&gt;&lt;li style="text-decoration: line-through;"&gt;Add text to the page describing the game controls&lt;/li&gt;&lt;li style="text-decoration: line-through;"&gt;Fix projectile management (I wasn't tracking them correctly, especially the sword)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The other changes are things I added because I felt they were necessary and/or appropriate to be done at this time:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Added a "please wait" text blurb and animation to indicate game loading state&lt;/li&gt;&lt;li&gt;Re-encoded the music at lower bitrates: smaller file sizes, and more accurate to the original sounds.&lt;/li&gt;&lt;li&gt;Added a preliminary savegame screen; for now it just lists the available quest(s)&lt;/li&gt;&lt;li&gt;Added a few of the missing sound effects to the game (bombs boom, Link grunts when hit, etc)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As always, there's plenty to work on, and more coming soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5304413750358956749?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5304413750358956749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-05x.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5304413750358956749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5304413750358956749'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-05x.html' title='Cloning Zelda: 0.5.x'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5322533986682645767</id><published>2009-10-14T10:54:00.007-05:00</published><updated>2010-01-11T23:44:00.255-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Cloning Zelda: Adding a Title Screen</title><content type='html'>&lt;img src="http://buyog.com/code/loc/Canvassa/loc/res/title.png" alt="Legend of Zelda title screen"/&gt;&lt;br/&gt;

&lt;p&gt;First, a note on the server move: you may have noticed that my domain was offline for a few days last week; this was because I flubbed the domain transfer to my new server. Anyway, all was eventually straightened out, and I've successfully migrated all of my content from the old server to the new one. If you see anything here on the site that's broken, post a comment and let me know.&lt;/p&gt;

&lt;p&gt;Now, on to today's subject: in trying to add several new states to the Game class for &lt;a href="http://buyog.com/code/loc/Canvassa"&gt;Canvassa&lt;/a&gt;, I've learned something interesting about Javascript's &lt;strong&gt;in&lt;/strong&gt; operator: &lt;em&gt;it doesn't really work for arrays!&lt;/em&gt; More specifically, it does in fact work, just not the way one would expect.&lt;/p&gt;

&lt;p&gt;I do a lot of work in Python. In that language, you can do something like the following, and have a reasonable expectation of success:&lt;/p&gt;

&lt;pre class="brush: python"&gt;
&gt;&gt;&gt; myList = [5,10,15,20]
&gt;&gt;&gt; print (10 in myList)
True
&lt;/pre&gt;

&lt;p&gt;So in a nutshell, you can define a list of values, and then check a reference value for membership in that list. Simple, and useful. I was doing this in Canvassa's &lt;em&gt;Game&lt;/em&gt; class to test for the existence of a caller-specified game state before actually changing to the new state:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
    this.constants.states = { overworld: 0, inventory: 1, 
                              dungeon: 2, map: 3, 
                              dying: 4, gameover: 5, cheat: 99, 
                              enum: [0,1,2,3,4,5,99] };
    ...
    changeState: function game_changeState(newState) {
        if (newState in this.constants.states.enum) {
            this.currentState = newState;
            this.drawBG();
        } else {
            console.log("Game.changeState() -- invalid state:", newState);
        }
    }
&lt;/pre&gt;

&lt;p&gt;So basically I was using game.constants.states.enum as a list to keep track of the valid state values that changeState() should accept. Since the states I was using were all 0-based and sequential (except for the "cheat" state, which I haven't tested since &lt;a href="http://buyog.com/code/loc/part2"&gt;Part 2&lt;/a&gt; or so), this worked just fine. But in truth, it wasn't actually doing what I thought it was doing, as I was about to find out (dun-&lt;em&gt;dun-&lt;strong&gt;DUN&lt;/strong&gt;&lt;/em&gt;!)&lt;/p&gt;

&lt;p&gt;I've been bothered for a while now about how I was loading the quest data (which handles map layouts, item and monster placement, and so on). Basically I was using the &lt;a href="http://docs.dojocampus.org/dojo/require"&gt;dojo.require()&lt;/a&gt; function to lazy-load the _quest1.js file, which doesn't actually contain a dojo class definition, but simply assigned the quest data to a namespaced variable, loc.gameData, which my classes could then refer to as a global. All kinds of poor, hackish behavior going on there. Plus, I'm building this game engine to support multiple (and, eventually, user-created) quests, so hard-coding one into the game bootstrapping logic is stupid and short-sighted. In order to correct this egregious flaw in the least destructive way possible, I reasoned, I should add several new states to the Game class, using negative integers to represent these meta-states that exist outside the regular game loop:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
    this.constants.states = { title: -1, menu: -2, loading: -3,
                              overworld: 0, inventory: 1, 
                              dungeon: 2, map: 3, 
                              dying: 4, gameover: 5, cheat: 99, 
                              enum: [-3,-2,-1,0,1,2,3,4,5,99] };
&lt;/pre&gt;

&lt;p&gt;In theory, the game engine could now start in the &lt;em&gt;title&lt;/em&gt; state, and when the player presses start, change to the &lt;em&gt;menu&lt;/em&gt; state, then allow quest selection from there. (for now, I'm simply &lt;a href="dojocampus.org/content/tag/dojoxhrget/"&gt;XHR-loading&lt;/a&gt; _quest1.js when the user presses start, and will add the menu state later). But instead of working as I expected, this is when everything started to fall apart. I made the above change and a few others that would direct the game to load the necessary image resources, and then call game.changeState(game.constants.states.title) to display the title screen. BOOM! JavaScript error:&lt;/p&gt;

&lt;pre style="color:red;"&gt;
Game.changeState() -- invalid state: -1
&lt;/pre&gt;

&lt;p&gt;Spending some time testing various expressions in the Firebug console, I eventually &lt;a href="http://twitter.com/buyog/status/4853972957"&gt;figured it out&lt;/a&gt;: 
the 'in' operator, when applied to JavaScript arrays, tests for the existence of a given &lt;em&gt;index&lt;/em&gt;, not value! Observe this little exchange from my Firebug console:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
&gt;&gt;&gt; game.constants.states.enum
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 99]
&gt;&gt;&gt; -1 in game.constants.states.enum
false
&gt;&gt;&gt; 8 in game.constants.states.enum
true
&lt;/pre&gt;

&lt;p&gt;Like I said on Twitter when I discovered this: &lt;a href="http://twitter.com/buyog/status/4854016028"&gt;Freaky!&lt;/a&gt; I spent a few minutes looking at ways to get around this apparent misbehavior on JavaScript's part (I've since come to terms with why it works the way it does, but it's totally counter-intuitive to my way of thinking), and found &lt;a href="http://snook.ca/archives/javascript/testing_for_a_v"&gt;this method&lt;/a&gt;, suggested by JavaScript rockstar &lt;a href="http://snook.ca/about/"&gt;Jonathan Snook&lt;/a&gt;. 

&lt;blockquote&gt;
In JavaScript, there's an in operator that tests whether a property is in an object. We can actually use this to mimic the PHP function in_array.

&lt;pre&gt;if(name in {'bobby':'', 'sue':'','smith':''}) { ... }&lt;/pre&gt;

If the value of name matches any of the keys in the object literal, it returns true. 
&lt;/blockquote&gt;

&lt;p&gt;Jonathan then offers a refinement via a small function that takes a string array as input, and returns an object literal that can then be tested for membership via &lt;strong&gt;in&lt;/strong&gt;. A reasonable approach, but not really one I wanted to pursue, if something simpler would work. This is what I came up with:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
    this.constants.states = { overworld: 'overworld',
                              inventory: 'inventory',
                              dungeon: 'dungeon',
                              map: 'map',
                              dying: 'dying',
                              gameover: 'gameover',
                              title: 'title',
                              menu: 'menu',
                              loading: 'loading',
                              cheat: 'cheat' };
    ...
    changeState: function game_changeState(newState) {
        if (newState in this.constants.states) {
            this.currentState = newState;
            this.drawBG();
        } else {
            console.log("Game.changeState() -- invalid state:", newState);
        }
    }
&lt;/pre&gt;

&lt;p&gt;Et, voila! Simple and elegant. I still have my pseudo-enumeration of valid game states, but I've eliminated the unnecessary "enum: [1,2,3...]" construction, and changed the state values from meaningless integers into strings that matched their own keys. Now my code can still refer to states via their game.constants.states.* enumeration values, and &lt;strong&gt;in&lt;/strong&gt; works as expected, since those strings resolve as properties of the game.constants.states object literal.&lt;/p&gt;

&lt;p&gt;There was a little more code cleanup necessary to support this change (for instance, I had to define a list of "unpausable" states so that the user wouldn't be able to put the game in pause mode from the title screen), and there are still a few lingering, unrelated problems in the 0.5 codebase, but we now have a title screen, and the ability to add new game states and check for their existence. All in all, a good night's work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5322533986682645767?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5322533986682645767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-adding-title-screen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5322533986682645767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5322533986682645767'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-adding-title-screen.html' title='Cloning Zelda: Adding a Title Screen'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-3428222584998597500</id><published>2009-10-02T09:00:00.004-05:00</published><updated>2010-01-11T23:44:00.256-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Cloning Zelda: Progress and a Change of Methodology</title><content type='html'>&lt;p&gt;So those of you who are hitting the work-in-progress &lt;a href="/code/loc/Canvassa"&gt;Canvassa&lt;/a&gt; build may have noticed that I've added sound support back in. It's not very Dojo-y at the moment, but I got tired of not hearing anything as I tested, so it's in. I've also got the bug about predefined items (e.g. the sword on screen 1) reappearing after you pick them up.&lt;/p&gt;&lt;p&gt;The other major change in the &lt;a href="/code/loc"&gt;Canvassa&lt;/a&gt; effort is how I'll be measuring progress. I started out treating it almost as a tutorial of how to build a game like this in JavaScript+Dojo, and to a certain extent I'll continue to do so, but the posts will stray from the "Part 1 / 2a / 2b..." format that I've been using, and go to a slightly more traditional "dot release" approach: right now I'm working on version 0.5, and when it's finished and the &lt;a href="http://github.com/buyog/Canvassa/"&gt;Github repository&lt;/a&gt; is updated, I'll move to v0.6. All development will be done in the work-in-progress &lt;a href="/code/loc/Canvassa"&gt;Canvassa&lt;/a&gt; location, so no more &lt;a href="/code/loc/Part1"&gt;Part 1&lt;/a&gt; / &lt;a href="/code/loc/Part2"&gt;Part 2&lt;/a&gt; / etc. subfolders. Hopefully this will be easier for me to work with and stay on task, and will be more in line with what you, my faithful reader, would want to see anyway. (of course, if I'm wrong in my estimation, feel free to let me know in the comments).&lt;/p&gt;&lt;p&gt;Beyond that, not much else has progressed this week; I'll be moving this blog and &lt;a href="/"&gt;my&lt;/a&gt; &lt;a href="/MUGEN"&gt;others&lt;/a&gt; to &lt;a href="http://www.dreamhost.com"&gt;my new host&lt;/a&gt; soon, and I'm still trying to decide how exactly I want to set things up (one of the main points of uncertainty is whether to keep the three blogs separate, or merge them into a single stream with tags/categories to differentiate them. If I &lt;em&gt;do&lt;/em&gt; merge the blogs, I'll keep my RSS feeds the same (I'll re-orient the FeedBurner links to point to the appropriate places), so those of you reading me through a feed reader probably won't notice much of a difference. Hopefully, I'll be able to get the buyog.com domain transferred over smoothly to my new host as well, but if not, the buyog.net domain will get you to the new content. When the move actually happens, I'll make a note of it here so you're all aware.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-3428222584998597500?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/3428222584998597500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-progress-and-change-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3428222584998597500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3428222584998597500'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/10/cloning-zelda-progress-and-change-of.html' title='Cloning Zelda: Progress and a Change of Methodology'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-8653756846635854349</id><published>2009-09-24T18:15:00.000-05:00</published><updated>2009-09-24T18:15:00.410-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Canvassa 0.5 Bug List</title><content type='html'>&lt;p&gt;Thought I'd peel back the curtain a little tonight. Here's what's left to do with my &lt;a href="/code/loc/Canvassa"&gt;Canvassa&lt;/a&gt; Zelda clone before I can call version 0.5 (i.e. Part 5) done and ready to move on to 0.6:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Add text to the page describing the game controls&lt;/li&gt;&lt;li&gt;Fix projectile management (I'm not keeping track of them correctly, especially the sword)&lt;/li&gt;&lt;li&gt;Add the sword projectile "flash" effect when it hits something&lt;/li&gt;&lt;li&gt;Limit the blue candle to a single use per screen&lt;/li&gt;&lt;li&gt;Make Link &amp;amp; the monsters get knocked back when hit&lt;/li&gt;
&lt;li&gt;Fix the number of hits required to kill monsters (esp. Zola)&lt;/li&gt;&lt;li&gt;Permanently remove predefined items from the map when picked up (e.g. the wooden sword on the start screen -- grab it, leave the screen, then come back: it's there again!)&lt;/li&gt;&lt;li&gt;Make killed monsters leave behind hearts and rupees (fairies and clocks come later)&lt;/li&gt;&lt;li&gt;Split Items.js file into multiple subfiles, parallel to what Peter Higgins did to Monsters.js for me &lt;a href="/code/2009/09/cloning-zelda-with-little-help-from-my.html"&gt;last week&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I'll be working on a few of these things tonight; maybe even have a more verbose blog post to go along with it (hope springs eternal, anyway)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-8653756846635854349?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/8653756846635854349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/canvassa-05-bug-list.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8653756846635854349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/8653756846635854349'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/canvassa-05-bug-list.html' title='Canvassa 0.5 Bug List'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2134671662071448537</id><published>2009-09-16T13:25:00.002-05:00</published><updated>2009-09-16T13:57:06.042-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: With a Little Help from my Friends...</title><content type='html'>&lt;p&gt;My Twitter friend &lt;a href="http://twitter.com/phiggins"&gt;Peter Higgins&lt;/a&gt;, who &lt;a href="/code/2009/04/jsconf-tweets.html"&gt;I've mentioned before&lt;/a&gt;, has been following my progress on Canvassa for the past several months, and last week he sent me a brief message, asking if I'd be okay with him forking the &lt;a href="http://github.com/buyog/Canvassa/"&gt;code on Github&lt;/a&gt; to re-arrange the overall structure of the app and make it more Dojo-y. I said sure, because anytime you've got someone with his programming chops offering to partner with you to help make your code better, &lt;a href="http://www.codinghorror.com/blog/archives/001229.html"&gt;you don't say no&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;So anyway, a few days later, Peter sent me a Github pull request to take a look at &lt;a href="http://github.com/phiggins42/Canvassa"&gt;his branch&lt;/a&gt;, and yes, it's quite different. So different, in fact, that I haven't yet figured out yet how to integrate his changes back into the trunk! But a couple of things jumped out at me:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;He moved all of the namespaced code (basically all of my Dojo classes) into a subfolder off the main folder, so now you have /loc/Canvassa/index.html for the main page, but the game classes all live in /loc/Canvassa/loc.&lt;/li&gt;&lt;li&gt;He split up the Monster classes into individual .js files, and put them in a subfolder under the namespaced folder (/loc/Canvassa/loc/Monster)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In the short term, this has resulted in a LOT more http requests when the game is initially loaded. Long-term, though, it'll help since you only have to download the monster classes that have actually changed instead of re-grabbing the entire code glob when I tweak something about, say, the Octorok's behavior. And when the long-awaited day arrives that I put the "it's done" seal on this project, I can use &lt;a href="http://shrinksafe.dojotoolkit.org/"&gt;Dojo ShrinkSafe&lt;/a&gt; to merge and minify all of the code into a single package, eliminating the multiple-http-requests problem.&lt;/p&gt;&lt;p&gt;For the time  being, I've put my working copy of Peter's branch on my site &lt;a href="/code/loc/Canvassa"&gt;here&lt;/a&gt;. It's slightly more functional than the version in my &lt;a href="/code/loc/part5"&gt;Part 5&lt;/a&gt; working copy, including updates to medicine (it works), bait (it kinda-sorta works, but doesn't affect enemy AI yet), and the bombs and candle (they both more or less work now, but don't destroy scenery yet). But in the process of those updates, I somehow managed to break the boomerang, so I need to fix that before I attempt to merge it back into the trunk and blog about what I did to implement the new item behaviors. Hopefully that'll be a simple fix; I suspect I just broke something minor in the loc.Item base class.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2134671662071448537?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2134671662071448537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/cloning-zelda-with-little-help-from-my.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2134671662071448537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2134671662071448537'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/cloning-zelda-with-little-help-from-my.html' title='Cloning Zelda: With a Little Help from my Friends...'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-3253741199001259622</id><published>2009-09-09T09:49:00.004-05:00</published><updated>2010-01-11T23:44:00.257-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Cloning Zelda: Back-to-School update</title><content type='html'>&lt;p&gt;After taking a sanity break from my JavaScript/HTML5/Canvas &lt;a href="/code/loc"&gt;Zelda clone&lt;/a&gt; I've been making for the past several months, I've started banging on it again, but haven't been able to muster the energy to actually blog about it, perhaps because the things I've been doing aren't all that technically interesting, just important to do (case in point: I've had the bow &amp;amp; arrow working for a while, but until yesterday's update, it wasn't tied to your rupee count as it was supposed to be). As of this morning, the sword, boomerang, bow, and magic wand are all working more or less as they should be (you can't throw the boomerang diagonally yet, and the wand produces magic waves without you actually waving it, but those are both minor quibbles like the arrow-rupee thing), and I've implemented a cheat code to grant you all items so you can actually, y'know, test them (hint: it uses the &lt;a href="http://en.wikipedia.org/wiki/Konami_Code"&gt;Konami Code&lt;/a&gt;, or you can just mash the "ALL ITEMS" button down in the corner of the screen)&lt;/p&gt;

&lt;p&gt;A couple of the remaining items, however, promise to be interesting: bombs and candles both behave differently than standard projectiles, and the flute, bait, and letter aren't projectiles at all (well, I suppose you could think of the bait as a projectile in the same way that the bomb is, but still... it doesn't actually kill enemies, just attract them). Each of these has the promise of interesting blog fodder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bomb&lt;/strong&gt;: drop a bomb, and after a moment it spawns multiple "explosion" artifacts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;candle&lt;/strong&gt;: spawns a flame projectile, but it only goes a limited distance and not clear across the screen like the others&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;flute&lt;/strong&gt;: spawns a whirlwind object that picks up the player and warps them to the location of the dungeons&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bait&lt;/strong&gt;: like the bomb, since you just drop it instead of throwing it -- but it doesn't explode or kill the enemies, it just alters their AI behavior&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;letter&lt;/strong&gt;: causes the old lady &lt;acronym title="Non-Player Character"&gt;NPC&lt;/acronym&gt; to sell you medicine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;medicine&lt;/strong&gt;: refills your health and then self-destructs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So as I implement these remaining items, I may jot some notes about why each is interesting to implement, and then I'll have something worth talking about here.&lt;/p&gt;

&lt;p&gt;Meanwhile, go see the stuff that's already done &lt;a href="/code/loc/part5/index.html"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-3253741199001259622?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/3253741199001259622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/cloning-zelda-back-to-school-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3253741199001259622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3253741199001259622'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/09/cloning-zelda-back-to-school-update.html' title='Cloning Zelda: Back-to-School update'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1894547352948450514</id><published>2009-08-19T21:55:00.003-05:00</published><updated>2009-09-10T13:14:36.110-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>NES Emulator in JavaScript? No Way!</title><content type='html'>Yes way, Ted: &lt;a href="http://benfirshman.com/projects/jsnes/"&gt;JSNES&lt;/a&gt;.

What this means to me personally: well, I'm going to continue working on &lt;a href="/code/loc"&gt;Canvassa&lt;/a&gt;, because ultimately it's the quest builder that I'm most excited about. But, I've still got to duplicate the existing functionality before I try to rewrite it all.

This summer has ended up being much more hectic than I'd anticipated, but the work will progress, and I'll try to be better about my weekly updates here, even if it's just to post to cool stuff like this JavaScript-based NES emulator. Tell me that thing's not inspiring to all you JS hackers out there.

At least, it is to me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1894547352948450514?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1894547352948450514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/08/nes-emulator-in-javascript-no-way.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1894547352948450514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1894547352948450514'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/08/nes-emulator-in-javascript-no-way.html' title='NES Emulator in JavaScript? No Way!'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6146279932789055921</id><published>2009-07-23T00:21:00.006-05:00</published><updated>2009-09-10T13:14:36.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Next Cloning Target...?</title><content type='html'>&lt;p&gt;I know I owe a &lt;a href="http://www.buyog.com/code/loc/"&gt;Canvassa&lt;/a&gt; update, and seriously, it is coming -- I've just been distracted lately. By things like this awesome fan-made MegaMan game being made:&lt;/p&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/zygjot2YV4Q&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/zygjot2YV4Q&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;p&gt;A few months ago I met &lt;a href="http://twitter.com/ryanmcgrath"&gt;Ryan McGrath&lt;/a&gt; at &lt;a href="http://www.buyog.com/code/2009/04/jsconf-2009.html"&gt;JSConf 2009&lt;/a&gt; (a Javascript developers conference), and he mentioned to me that he'd been toying with making a web-based MegaMan game. His comment, and seeing what MegaPhilX and N64Mario are doing with this custom MegaMan engine, has put the "bug in my ear," so to speak. So at some point in the future when I'm done working on the Zelda clone... well then, looks like it may be MegaMan's turn.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6146279932789055921?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6146279932789055921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/next-cloning-target.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6146279932789055921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6146279932789055921'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/next-cloning-target.html' title='Next Cloning Target...?'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5501844345037721650</id><published>2009-07-14T11:27:00.002-05:00</published><updated>2010-01-11T23:44:00.258-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Hiatus?</title><content type='html'>&lt;p&gt;Quick Tuesday post this week, with a request for feedback embedded at the end.&lt;/p&gt;&lt;p&gt;I'm posting this from work while on my lunch break. Last Friday, something of a dam burst here at work, and I'm now flooded with work to do, where a week ago I was a little light on projects from time to time. This has the side effect of giving me less time to think about the content I'll be producing for the site here... although I actually did the vast majority of my blog work "off the clock", there were lulls where I could at least brainstorm solutions to problems (like the whole "&lt;a href="http://www.buyog.com/code/2009/06/cloning-zelda-part-5d-scaling-math-wall.html"&gt;Math Wall&lt;/a&gt;" thing, for example) -- now, not so much.&lt;/p&gt;&lt;p&gt;On top of this massive shift in my work environment, I spent last weekend &lt;a href="http://www.buyog.com/2009/07/home.html"&gt;moving my family&lt;/a&gt; into a new home / state / city / etc. This means a home new internet provider is necessary... and they won't be able to come and hook me up until this coming Friday. So... the big loser in all of this is my blogging. Once my home internet is up and running again I should be back in business, but until then things are, sadly, on hold.&lt;/p&gt;&lt;p&gt;Now, to that request for feedback I mentioned at the beginning of this post: I've recently set up a new domain at &lt;a href="http://buyog.net"&gt;buyog.net&lt;/a&gt;, and have installed a &lt;a href="http://blog.buyog.net"&gt;WordPress-powered blog&lt;/a&gt; over there. Here's the question: should I merge my three Blogger-powered blogs (&lt;a href="http://www.buyog.com"&gt;Buyog's World&lt;/a&gt; (the root blog), &lt;a href="http://www.buyog.com/MUGEN"&gt;Buyog's Lair&lt;/a&gt; (the MUGEN blog), and &lt;a href="http://www.buyog.com/code"&gt;Palagpat Coding&lt;/a&gt; (this web programming/gaming blog) into a single master blog, separated by categories? The content of these three blogs, and presumably the resulting audience for each, seems to me to be so diverse that merging them would be counter-productive. But I'm interested in seeing what people think. Let me know below in comments, or feel free to email me at buyog2099(at)gmail.com.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5501844345037721650?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5501844345037721650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/hiatus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5501844345037721650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5501844345037721650'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/hiatus.html' title='Hiatus?'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-9076080720949434576</id><published>2009-07-08T17:13:00.002-05:00</published><updated>2010-01-11T23:44:00.260-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Watch this space</title><content type='html'>I know, I'm late again with my weekly Tuesday update, and for that I apologize. The short explanation is that &lt;a href="http://www.buyog.com/2009/06/house-is-now-officially-ours.html"&gt;I'm moving this week&lt;/a&gt;, so am very much in the thick of packing right now. I have Part 6A of my "&lt;a href="/code/loc"&gt;Cloning Zelda&lt;/a&gt;" series almost ready to go, but haven't had the time to write it up right, yet. I'm shooting to get it up before the move this Friday, but if that doesn't happen, look for a more-substantial-than-usual update next week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-9076080720949434576?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/9076080720949434576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/watch-this-space.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/9076080720949434576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/9076080720949434576'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/07/watch-this-space.html' title='Watch this space'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1706035941456731882</id><published>2009-06-30T23:49:00.002-05:00</published><updated>2009-07-01T00:00:16.437-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Firefox 3.5</title><content type='html'>&lt;p&gt;Quick post this week; there's too much going on in my personal life (see my &lt;a href="/"&gt;root blog&lt;/a&gt; for details) for a full update.&lt;/p&gt;

&lt;p&gt;After months of anticipation, Firefox finally &lt;a href="http://en-us.www.mozilla.com/en-US/firefox/3.5/whatsnew/"&gt;released version 3.5&lt;/a&gt; today. And I must say, so far it seems very worth the wait. If you're still using Internet Explorer (even the better-but-still-nonstandard version 8), you owe it to yourself to give Firefox a try.&lt;/p&gt;

&lt;p&gt;Also, to make this just a tiny bit more related to my blog, I tested the latest &lt;a href="/code/loc"&gt;Canvassa&lt;/a&gt; pages (the &lt;a href="/code/loc/part5/index.html"&gt;game&lt;/a&gt;, &lt;a href="/code/loc/part5/sprites2.html"&gt;Bestiary&lt;/a&gt;, and &lt;a href="/code/loc/part5/mapper.html"&gt;Mapper&lt;/a&gt;) in FF 3.5, and they all seemed to benefit from the new-and-improved JavaScript engine.&lt;/p&gt;

&lt;p&gt;Next week (or sooner), I hope to have a new post up in the &lt;a href="/code/labels/Zelda.html"&gt;Cloning Zelda&lt;/a&gt; series... if I can just get the item states / animations resolved.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1706035941456731882?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1706035941456731882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/firefox-35.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1706035941456731882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1706035941456731882'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/firefox-35.html' title='Firefox 3.5'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6666239203788488307</id><published>2009-06-22T23:12:00.012-05:00</published><updated>2009-06-23T00:49:15.806-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Simple tag cloud generator in JavaScript</title><content type='html'>&lt;p&gt;After having to roll my own tag cloud generator for &lt;a href="http://www.buyog.com/2009/06/problem-of-categorization.html"&gt;my&lt;/a&gt; &lt;a href="http://www.buyog.com/MUGEN/2009/06/new-site-features-tagslabels.html"&gt;blogs&lt;/a&gt; (I'm old-school, so I don't have access to a blog layout engine with prebuilt widgets), I thought I'd clean up the code and share it. So, it's in &lt;a href="http://github.com/buyog/MiscJS"&gt;this new repository&lt;/a&gt; I just created on GitHub.&lt;/p&gt;

&lt;p&gt;Usage is pretty simple; copy the JS (and optional CSS) to your server, and link to them from your blog code like so:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
  &amp;lt;style type="text/css"&amp;gt;
    @import "http://www.myblog.com/css/tagCloud.css";
  &amp;lt;/style&amp;gt;
  &amp;lt;script type="text/javascript" src="http://www.myblog.com/js/tagCloud.js"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Once you've got it loaded, there are only two steps to create a new tag cloud: first, you need to populate a JavaScript object with the tag information structured like an &lt;a href="http://www.quirksmode.org/js/associative.html"&gt;associative array&lt;/a&gt;, with the tag names as properties and the instance counts for each tag as its hash value. Ideally this will be retrieved via an AJAX/XHR request, but in a pinch you can hard-code it (but that's not terribly useful, since you'd have to constantly update it whenever you post something new):&lt;/p&gt;

&lt;pre class="brush: js"&gt;
    // hard-coded, pure JavaScript version:
    tags = {
      "JavaScript":17,
      "Conferences":2,
      ".NET":1,
      "GeoWeb":1,
      "Site news":1,
      "snippets":1,
      "Dojo":16
    };
    function init_tagCloud(parentId) {
      var parentDiv = document.getElementById(parentId);
      if (parentDiv) {
        var cloud = makeCloud(tags, "http://www.myblog.com/labels/", 0,1,4,' ');
        parentDiv.appendChild( cloud );
      }
    }
    window.onload = function() {
      init_tagCloud('target_div');
    }

    // or, Dojo-powered and XHR-populated (substitute JS lib of your choice):
    dojo.addOnLoad(function() {
      dojo.xhrGet({
        url: "getBlogCategories.php",
        handleAs: "json",
        load: function(data){
          tags = data;
          var cloud = makeCloud(tags, "http://www.myblog.com/labels/", 0,1,4,' ');
          dojo.byId('target_div').appendChild( cloud );
        }
      });
    });
&lt;/pre&gt;

&lt;p&gt;The parameters on the &lt;em&gt;makeCloud()&lt;/em&gt; method are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;tags&lt;/em&gt;: the object hash mentioned above&lt;/li&gt;&lt;li&gt;&lt;em&gt;baseUrl&lt;/em&gt;: the URL that should serve as the base for all tag links&lt;/li&gt;&lt;li&gt;&lt;em&gt;minCount&lt;/em&gt;: minimum number of times tag must be used to show up in the cloud (defaults to 0)&lt;/li&gt;&lt;li&gt;&lt;em&gt;minSize&lt;/em&gt;: minimum font size for tags in the cloud (defaults to 1em)&lt;/li&gt;&lt;li&gt;&lt;em&gt;max&lt;/em&gt;: maximum font size for tags in the cloud (defaults to 4.5em)&lt;/li&gt;&lt;li&gt;&lt;em&gt;delim&lt;/em&gt;: delimiter(s) to insert between tags in the cloud (defaults to 1 space)&lt;/li&gt;&lt;li&gt;&lt;em&gt;shuffle&lt;/em&gt;: boolean value that controls if the tags get shuffled in random order, or sorted (defaults to false)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;That's about all there is to say about it. The basic math for determining the tag size is taken almost verbatim from the &lt;a href="http://en.wikipedia.org/wiki/Tag_cloud"&gt;Wikipedia page&lt;/a&gt; on tag clouds, just slightly tweaked to allow for a minimum font size. Surely there are other customizations that could be made, and ideally this would be implemented as a &lt;a href="http://higginsforpresident.net/2009/03/a-dojo-plugin-pattern/"&gt;Dojo/plugd-style plugin&lt;/a&gt;. I'll leave that for an exercise at a later date.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;--Edit: I inadvertently forgot to strip out the &amp;lt;script&amp;gt; tags from the sample code blocks up above, and they were getting run! D'oh!&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6666239203788488307?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6666239203788488307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/simple-tag-cloud-generator-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6666239203788488307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6666239203788488307'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/simple-tag-cloud-generator-in.html' title='Simple tag cloud generator in JavaScript'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1228718644687888589</id><published>2009-06-16T19:29:00.003-05:00</published><updated>2009-09-10T13:14:36.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Are we done yet?</title><content type='html'>&lt;P&gt;Busy with graduate school projects tonight, so this week's Tuesday post (okay, it's Wednesday morning) will be short.&lt;/p&gt;

&lt;p&gt;The Overworld map is now implemented in the &lt;a href="http://www.buyog.com/code/loc/part5"&gt;Canvassa, Part 5&lt;/a&gt; main page, and I've ported the &lt;a href="http://www.buyog.com/code/loc/part5/mapper.html"&gt;Map Maker&lt;/a&gt; utility too, albeit in an optimized way (you have to actually click on a map screen in order to see its thumbnail, instead of having the page draw the entire map. I'm working on ways to draw all the thumbnails without bogging down the machine, but none of them are fully fleshed out yet).&lt;/p&gt;

&lt;p&gt;Left to do before I close out the Part 5 code branch:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Port over the rest of the inventory/items code&lt;/li&gt;
&lt;li&gt;Implement better map boundary checking (it's currently possible to slightly overlap walls and such)&lt;/li&gt;
&lt;li&gt;Post over the hit collision code from the earlier iteration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I've finished the above tasks, I'll consider the rewrite/re-engineering effort a success, write the final "Part 5" blog post, and move forward to Part 6. Depending on my school load the rest of this week, that may happen sometime before next Tuesday. If not... well, I'm sure I'll think of something.&lt;/p&gt;

&lt;p&gt;Reminder: the most recent version of the code is also available on &lt;a href="http://github.com/buyog/Canvassa/"&gt;GitHub&lt;/a&gt;, if you're interested in checking out the full source code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1228718644687888589?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1228718644687888589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-are-we-done-yet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1228718644687888589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1228718644687888589'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-are-we-done-yet.html' title='Cloning Zelda: Are we done yet?'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1404521475609443921</id><published>2009-06-10T21:25:00.002-05:00</published><updated>2009-09-10T13:14:36.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: Sandboxed</title><content type='html'>At &lt;a href="http://higginsforpresident.net/"&gt;Peter Higgins's&lt;/a&gt; suggestion, I've started a public sandbox on &lt;a href="http://github.com/buyog/Canvassa"&gt;Github&lt;/a&gt;, and the latest version of Canvassa is up there for your perusal. Feel free to review / fork / comment the heck out of it, if you so choose.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1404521475609443921?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1404521475609443921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-sandboxed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1404521475609443921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1404521475609443921'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-sandboxed.html' title='Cloning Zelda: Sandboxed'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2526187779401323093</id><published>2009-06-09T19:24:00.002-05:00</published><updated>2009-09-10T13:14:36.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 5D: Scaling the Math Wall</title><content type='html'>&lt;p style="font-size: smaller; font-variant: small-caps;"&gt;Previous posts in this series: &lt;a href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html" title="Intro"&gt;Part 1&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html" title="Sprite tiling"&gt;Part 2&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html" title="Map navigation"&gt;Part 3A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html" title="Adding monsters"&gt;Part 3B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html" title="Scaling up / scaling down"&gt;Part 4A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html" title="Adding sounds &amp;amp; music"&gt;Part 4B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-part-4-combat-finally.html" title="Adding sprite collision tests"&gt;Part 4C&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5-redefining-sprite.html" title="Refactoring the sprite engine"&gt;Part 5A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5b-preview.html" title="Creating a test harness for monster classes"&gt;Part 5B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/06/cloning-zelda-part-5c-building-better.html" title="More monsters, more AI, more projectiles"&gt;Part 5C&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I blogged &lt;a href="http://www.buyog.com/code/2009/06/cloning-zelda-part-5c-building-better.html"&gt;last week&lt;/a&gt; about the strides I've made with refactoring the various monster classes into the new sprite engine, and related how I got stuck, for the second time, trying to make the boomerang work right (I'd had it mostly implemented a while ago when I first decided to do the sprite engine refactoring, in large part because it didn't animate well in the old engine). Well, a few afternoons later, I knuckled down while on my lunch break and got it working. (&lt;em&gt;fair warning for the math-averse: the rest of this post is going to be pretty trigonometry-heavy&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;First, I owe a huge debt to a couple of sites that helped refresh my memory of vector geometry. I recalled the old "&lt;a href="http://www.mathopenref.com/coordslope.html"&gt;rise over run&lt;/a&gt;" rule for defining the slope of a vector or line, and I knew that the &lt;a href="http://en.wikipedia.org/wiki/Pythagorean_theorem"&gt;Pythagorean Theorem&lt;/a&gt; (a&lt;span class='exp'&gt;2&lt;/span&gt; + b&lt;span class='exp'&gt;2&lt;/span&gt; = c&lt;span class='exp'&gt;2&lt;/span&gt;) could be used to figure out the length of a vector &lt;em&gt;c&lt;/em&gt;, given its X and Y components &lt;em&gt;a&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt;. The rest took some memory-jogging: &lt;a href="http://www.topcoder.com/tc?module=Static&amp;d1=tutorials&amp;d2=geometry1"&gt;lbackstrom's tutorial&lt;/a&gt; at TopCoder.com was a good refresher, and the &lt;a href="http://whyslopes.com/Analytic-Geometry-Functions/analGeo09a_Lines_Equations_For.html"&gt;Slopes and Lines overview&lt;/a&gt; at WhySlopes.com filled in the rest (good thing, too, because my daughter is going to need me to help her with her geometry homework before I know it...)&lt;/p&gt;

&lt;p&gt;Anyway, the basic math of the boomerang problem works like this: when thrown, a boomerang has an initial vector that determines its movement in the X and Y directions. When it reaches its apogee or hits the edge of the screen, it then reverses course, homing in on its thrower. In order to do this, the boomerang version of the Projectile class had to override the base class's &lt;em&gt;updatePosition&lt;/em&gt;() function, which gets called from the game main loop:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
main: function game_main() {
...
  // move all active projectiles
  for (var j in this.items) {
      if ("updatePosition" in this.items[j]) { this.items[j].updatePosition(); }
  }
...
}
&lt;/pre&gt;

&lt;p&gt;(Note that we first have to check to see if each item in the game's item list actually &lt;em&gt;has&lt;/em&gt; the updatePosition() function, because non-projectile items, like dropped hearts and rupees, won't.) The boomerang projectile's &lt;em&gt;updatePosition&lt;/em&gt;() function looks like this:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
updatePosition: function boomProj_updatePosition() {
    // move me to the next point on my current trajectory
    this.pos.x += this.vel.x;
    this.pos.y += this.vel.y;

    // check to see if I've gone off the edge of the screen
    var offscreen = true;
    if (this.vel.x &lt; 0) {
        // moving left; check left edge
        offscreen &amp;= (this.pos.x &lt;= game.constants.screenBound.left);
    } else if (this.vel.x &gt; 0) {
        // moving right; check right edge
        offscreen &amp;= (this.pos.x &gt;= game.constants.screenBound.right);
    }
    if (this.vel.y &lt; 0) {
        // moving up; check top edge
        offscreen &amp;= (this.pos.y &lt;= game.constants.screenBound.top);
    } else if (this.vel.y &gt; 0) {
        // moving down; check bottom edge
        offscreen &amp;= (this.pos.y &gt;= game.constants.screenBound.bottom);
    }

    // calculate distance from my owner (set in the constructor via dojo.mixin() args)
    var dx = this.owner.pos.x - this.pos.x;
    var dy = this.owner.pos.y - this.pos.y;
    var distance = Math.sqrt(dx*dx + dy*dy); // thanks, Pythagorus!
    if (this._returning) {
        // if we're already returning, check to see if we're close enough to our owner to be caught
        if (distance &lt;= 8) {
            this.owner.catchItem();
            this.terminate();
        }
    } else if (offscreen || distance &gt;= this.apogee) {
        this._returning = true;
    }

    // calculate return velocity, if we're on the return path
    if (this._returning) {
        // change my vector to match the direction from me to my owner; valid values are -1, 0, or 1
        this.vector = {x: (dx) ? dx/Math.abs(dx) : 0, y: (dy) ? dy/Math.abs(dy) : 0};

        if (dx &amp;&amp; dy) {
            // vector is on a diagonal; I need to calculate both x and y components of velocity
            var slope = dy / dx;
            this.vel.x = Math.sqrt((this.speed*this.speed) / (slope*slope + 1)) * this.vector.x;
            this.vel.y = this.vel.x * slope;
        } else if (dx) {
            // dx only: horizontal vector
            this.vel = {x: this.speed * this.vector.x, y: 0};
        } else {
            // dy only: vertical vector
            this.vel = {x: 0, y: this.speed * this.vector.y};
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;A boomerang's return velocity is easy when it's strictly horizontal or vertical: the full measure of speed is devoted to either X or Y, respectively. The complicated part is when the boomerang is on a diagonal offset from its owner; in that case, the speed needs to be divided into X and Y components, in a ratio that matches that of the X and Y portions of the difference between the boomerang's current position, and that of the player (typically referred to as &amp;Delta;x and &amp;Delta;y, but which I called &lt;em&gt;dx&lt;/em&gt; and &lt;em&gt;dy&lt;/em&gt; in the code):&lt;/p&gt;

&lt;img src="http://www.buyog.com/code/images/loc_boomMath.png" alt="Link and the boomerang on a 2-d plane" style="float:left; padding: 0 10px 10px 10px;"/&gt;

&lt;p&gt;Subtracting the player's position from the boomerang's gives us the values for length of sides &amp;Delta;x and &amp;Delta;y: in this case, 30 and 43, respectively (note: the image is enlarged for clarity). The slope of the boomerang's velocity vector can be found by dividing &amp;Delta;x into &amp;Delta;y (Rise over run, remember?). That gives us:&lt;/p&gt;

&lt;pre&gt;slope = &amp;Delta;y / &amp;Delta;x = 30 / 43 &amp;asymp; 0.698&lt;/pre&gt;

&lt;p&gt;Now comes the tricky part: we know the total velocity of the boomerang, &lt;em&gt;Vel&lt;sub&gt;total&lt;/sub&gt;&lt;/em&gt;, as it needs to be equal to the predetermined speed for boomerangs: 3 pixels per frame. But, we don't know either the X or Y components of the velocity, which is what we need in order to do the right thing in &lt;em&gt;updatePosition&lt;/em&gt;(). Dredging up an old trick I learned in high school algebra, I remembered that if you have two unknown variables, you can solve them both if you can find two interrelated equations. Fortunately, we have them: the Pythagorean theorem, and the slope ratio. We'll figure out the x-component of the velocity &lt;em&gt;Vel&lt;sub&gt;x&lt;/sub&gt;&lt;/em&gt; first, because that will make the calculation of the y-component &lt;em&gt;Vel&lt;sub&gt;y&lt;/sub&gt;&lt;/em&gt; easy. Solving the Pythagorean Theorem for &lt;em&gt;Vel&lt;sub&gt;x&lt;/sub&gt;&lt;/em&gt;, we get:&lt;/p&gt;

&lt;pre style="clear: both;"&gt;
Vel&lt;sub&gt;total&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; = Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; + Vel&lt;sub&gt;y&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; + (Vel&lt;sub&gt;x&lt;/sub&gt; * slope)&lt;sup&gt;2&lt;/sup&gt; -- &lt;em&gt;(substituting in the slope formula: Vel&lt;sub&gt;y&lt;/sub&gt; = Vel&lt;sub&gt;x&lt;/sub&gt; * slope)&lt;/em&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; + (Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; * slope&lt;sup&gt;2&lt;/sup&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; * (1 + slope&lt;sup&gt;2&lt;/sup&gt;)
Vel&lt;sub&gt;x&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; = Vel&lt;sub&gt;total&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; / (1 + slope&lt;sup&gt;2&lt;/sup&gt;)
Vel&lt;sub&gt;x&lt;/sub&gt; = &amp;radic;&lt;span style="border-top:1px solid black"&gt; Vel&lt;sub&gt;total&lt;/sub&gt;&lt;sup&gt;2&lt;/sup&gt; / (1 + slope&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;radic;&lt;span style="border-top:1px solid black"&gt; 3&lt;sup&gt;2&lt;/sup&gt; / (1 + 0.698&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;radic;&lt;span style="border-top:1px solid black"&gt; 9 / (1 + 0.487)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;radic;&lt;span style="border-top:1px solid black"&gt; 6.052 &lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; = 2.460
&lt;/pre&gt;

&lt;p&gt;Then, solving for &lt;em&gt;Vel&lt;sub&gt;y&lt;/sub&gt;&lt;/em&gt;:&lt;/p&gt;

&lt;pre style="clear: both;"&gt;
Vel&lt;sub&gt;y&lt;/sub&gt; = Vel&lt;sub&gt;x&lt;/sub&gt; * slope
&amp;nbsp;&amp;nbsp;&amp;nbsp; = 2.460 * 0.698
&amp;nbsp;&amp;nbsp;&amp;nbsp; = 1.717
&lt;/pre&gt;

&lt;p&gt;So in this instance, the X and Y components of the boomerang's velocity should be set to 2.46 and 1.71708. Now that we've worked it out, these calculations can be done every time the game calls &lt;em&gt;updatePosition&lt;/em&gt;(), and in all but the most extreme cases (i.e. 20 Goriyas in a dungeon room, all throwing boomerangs at the same time) this won't cause any measurable slowdown.&lt;/p&gt;

&lt;p&gt;You can see the results for yourself, by loading up the latest iteration of the game, &lt;a href="http://www.buyog.com/code/loc/part5/index.html"&gt;here&lt;/a&gt;. The arrow keys control the player's movement, and the Z and X keys throw the boomerang and sword, but the map and inventory screens aren't converted to the new codebase yet, so that's the next order of business. I've also added some preliminary code that should take care of preloading all necessary resources, but it's still a bit buggy, so if nothing happens when you first hit the page, hit refresh and try again. Of course you can also go to the &lt;a href="http://www.buyog.com/code/loc/part5/sprites2.html"&gt;Bestiary&lt;/a&gt; if you prefer, and see for yourself how the Goriyas can handle their boomerangs. Collision detection still isn't turned on yet, but I fully expect to have that for the next update.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2526187779401323093?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2526187779401323093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-part-5d-scaling-math-wall.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2526187779401323093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2526187779401323093'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-part-5d-scaling-math-wall.html' title='Cloning Zelda, part 5D: Scaling the Math Wall'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2763214167023022104</id><published>2009-06-03T01:07:00.004-05:00</published><updated>2009-09-10T13:14:36.111-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 5C: Building Better Monsters</title><content type='html'>&lt;p style="font-size: smaller; font-variant: small-caps;"&gt;Previous posts in this series: &lt;a href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html" title="Intro"&gt;Part 1&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html" title="Sprite tiling"&gt;Part 2&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html" title="Map navigation"&gt;Part 3A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html" title="Adding monsters"&gt;Part 3B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html" title="Scaling up / scaling down"&gt;Part 4A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html" title="Adding sounds &amp;amp; music"&gt;Part 4B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-part-4-combat-finally.html"&gt;Part 4C&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5-redefining-sprite.html"&gt;Part 5A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5b-preview.html"&gt;Part 5B&lt;/a&gt;&lt;/p&gt;

&lt;img src="http://www.buyog.com/code/images/loc_bestiary2.png" alt="Canvassa Bestiary with projectile attacks" style="padding: 0pt 7px 7px 0pt; float: left;"/&gt;
&lt;p&gt;&lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5b-preview.html"&gt;Last time&lt;/a&gt;, I introduced you to the &lt;a href="http://www.buyog.com/code/loc/part5/sprites2.html"&gt;Canvassa Bestiary&lt;/a&gt;, a test page I wrote to put the new sprite class hierarchy through its paces. Since then, we've &lt;a href="http://www.buyog.com/2009/05/weve-got-house.html"&gt;put an offer on a house&lt;/a&gt; and I've revised and submitted the prospectus for my MA project to my thesis committee. Plus my time commitments to my &lt;a href="http://www.woti.com" title="White Oak Technologies"&gt;full-time job&lt;/a&gt; and my &lt;a href="http://www.buyog.com/2009/05/catching-up-on-picture-pool.html"&gt;awesome family&lt;/a&gt;. So I've been a little &lt;span style="text-decoration:line-through;"&gt;stressed out&lt;/span&gt; distracted.

&lt;p&gt;That said, I have added projectile attacks to the monsters that should have them... so Moblins shoot arrows, Lynels throw swords, Octorocs spit rocks, and so on. I've also stubbed in the dungeon monsters, as I mentioned before (although most of them don't have the right AI yet), so Wizzrobes are in there with their magic x-ray wavy attack... things, and Goriyas have their boomerangs... but then I hit the "Math Wall." (insert scary music here if you're so inclined). I'd intended to re-enable collision detection tonight and blog about all the cool new stuff I can do with the new sprites engine I've built, but instead I got stuck on the math needed to calculate the returning trajectory of a boomerang when its owner has moved. It's a &lt;em&gt;lot&lt;/em&gt; more complicated than I expected it to be, mostly because I haven't had Geometry in like 20 years. (yikes!) Anyway, I'm close, but I'm also tired and ready for bed. (ugh, how'd it get to be 2:30am ?!?)&lt;/p&gt;

&lt;p&gt;So, collisions will have to wait for the next update, which I'm (perhaps irrationally) hoping will also include the ported map engine and the game inventory screen. Then I'll be back to where I was &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-part-4-combat-finally.html"&gt;&lt;em&gt;TWO MONTHS AGO&lt;/em&gt;&lt;/a&gt; (sigh). Except I'll be cross-platform, projectiles will work, and dungeon monsters will be there. So that'll be a net gain after all.&lt;/p&gt;

&lt;p&gt;To check out my handiwork, and fill the screen with monsters, click &lt;a href="http://www.buyog.com/code/loc/part5/sprites2.html"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2763214167023022104?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2763214167023022104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-part-5c-building-better.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2763214167023022104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2763214167023022104'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/06/cloning-zelda-part-5c-building-better.html' title='Cloning Zelda, part 5C: Building Better Monsters'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-4616012901335365834</id><published>2009-05-24T16:48:00.004-05:00</published><updated>2009-09-10T13:14:36.112-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 5B</title><content type='html'>&lt;p style="font-size: smaller; font-variant: small-caps;"&gt;Previous posts in this series: &lt;a title="Intro" href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html"&gt;Part 1&lt;/a&gt; | &lt;a title="Sprite tiling" href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html"&gt;Part 2&lt;/a&gt; | &lt;a title="Map navigation" href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html"&gt;Part 3A&lt;/a&gt; | &lt;a title="Adding monsters" href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html"&gt;Part 3B&lt;/a&gt; | &lt;a title="Scaling up / scaling down" href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html"&gt;Part 4A&lt;/a&gt; | &lt;a title="Adding sounds &amp;amp; music" href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html"&gt;Part 4B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-part-4-combat-finally.html"&gt;Part 4C&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/05/cloning-zelda-part-5-redefining-sprite.html"&gt;Part 5A&lt;/a&gt;&lt;/p&gt;

&lt;img style="float:left; padding: 0 7px 7px 0;" src="http://www.buyog.com/code/images/loc_bestiary.png" alt="bestiary"/&gt;&lt;p&gt;I haven't yet finished writing up all that I've done for the next installment of my &lt;em&gt;&lt;a href="http://www.buyog.com/code/loc"&gt;Cloning Zelda&lt;/a&gt;&lt;/em&gt; series, but in the meanwhile, I wanted to share the test page I've created to evaluate monster behavior, AI, and state management. It's here, at the &lt;a href="http://www.buyog.com/code/loc/part5/sprites2.html"&gt;Canvassa Bestiary&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A few notes on what the Bestiary does: arrow keys allow you to move Link around the canvas. Pushing the first set of buttons and selecting different radio options will change Link's animation and appearance; right now if you push the "Die" button, Link will in fact die, and the game simulation will end; you'll have to refresh the page to start it up again.&lt;/p&gt;

&lt;p&gt;The next two sets of buttons will let you spawn enemies into the canvas... the first group is for overworld enemies, and the second group is for dungeon enemies, which I hadn't yet tried to do. Each will spawn in the correct way for that monster type (e.g. Armos enemies start out in their statue state), and all have basic AI that will determine how they move (even Peahats, Zolas and Leevers now work more or less correctly, although Tectites still look strange when jumping). I haven't yet added projectile attacks or sprite collisions; that's why I haven't blogged a full entry about the Bestiary yet (I hope to have that for this week's regular update on Tuesday).&lt;/p&gt;

&lt;p&gt;Final technical note: I've tested the Bestiary in Firefox 3.0.10, Chrome, and MSIE 7 (IE is sloooow, but functional). Notably, I've also successfully tested it on my Windows Mobile smartphone, in Opera Mobile 9.5 beta! Again, it's slow, but even seeing it &lt;strong&gt;WORK&lt;/strong&gt; on my phone was pretty frigging cool. Hopefully the Javascript performance war that has been raging on desktop browsers for the past year, will next find its way to the mobile platforms. Ultimately I'd love to be able to develop games and apps in HTML5/canvas and deploy to both desktop and mobile browsers in one click. What a cool step forward &lt;em&gt;that&lt;/em&gt; will be.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-4616012901335365834?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/4616012901335365834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5b-preview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4616012901335365834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4616012901335365834'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5b-preview.html' title='Cloning Zelda, part 5B'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5585500967154224027</id><published>2009-05-19T11:35:00.004-05:00</published><updated>2009-06-19T14:30:01.354-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GeoWeb'/><title type='text'>Mapping headaches</title><content type='html'>&lt;p style="font-size:smaller;"&gt;Note: the next entry in my &lt;a href="http://www.buyog.com/code/loc"&gt;Cloning Zelda&lt;/a&gt; series is still in progress; for now, enjoy the following post on something completely different.&lt;/p&gt;

&lt;p&gt;I've been experimenting with Google's &lt;a href="http://code.google.com/apis/kml/documentation/kml_tut.html"&gt;KML&lt;/a&gt; standard for the past few days, as a sort of a gateway into understanding how &lt;a href="http://en.wikipedia.org/wiki/Map_projection"&gt;map projections&lt;/a&gt; work. Remember all that trigonometry you learned back in middle/high school, and you always wondered when you would ever use it (aeronautical engineers excepted, of course: you guys probably do this stuff all the time)? Well, anyway, I ran smack into that wall head-first. The most interesting thing I've learned is WHY the &lt;a href="http://en.wikipedia.org/wiki/Mercator_projection"&gt;Mercator projection&lt;/a&gt; gets so weird and distorted toward the north and south poles (warning, it's rather math-y).&lt;/p&gt;

&lt;p&gt;Basically, Mercator's big idea was to shove the Earth into a giant imaginary cylinder, and unfold it onto the inside of this giant invisible tube, then unwrap and flatten the tube. Simple so far, right? Except for two problems: first, if you've ever peeled an orange, you know that the curved surface of a sphere (or &lt;a href="http://en.wikipedia.org/wiki/Oblate_spheroid"&gt;nearly-a-sphere&lt;/a&gt;) doesn't lay flat unless you split it into fairly narrow strips. This is why some maps get broken into chunks: the &lt;a href="http://en.wikipedia.org/wiki/Sinusoidal_projection"&gt;Interrupted Sinusoidal&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Waterman_%22Butterfly%22_World_Map_Projection"&gt;Waterman "Butterfly"&lt;/a&gt; are two of the more interesting of these, but there are &lt;a href="http://www.progonos.com/furuti/MapProj/Dither/ProjInt/projInt.html"&gt;a lot of others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The second problem with rectangular map projections involves the poles, and this one was the big revelation to me: the trigonometric formula that Mercator used in his eponymous projection only works until you get close to the poles, at which point the horizontal stretching &lt;strong&gt;&lt;em&gt;approaches infinity&lt;/em&gt;&lt;/strong&gt;. No wonder, then, that Greenland looks as big as South America, and Alaska almost as big as Brazil!&lt;/p&gt;

&lt;p&gt;Back to KML: in trying to get a handle on Mercator's latitude-to-y-coordinate formula, I realized that I couldn't define the top and bottom points of my map, because they were infinite! So, how on earth was I supposed to calculate the distances in between, if I didn't have a baseline? I whipped up a simple &lt;a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;q=http%3A%2F%2Fwww.buyog.com%2Fcode%2Fmisc%2Flatlong.xml"&gt;test KML file&lt;/a&gt; to plot the main latitude lines in 10-degree steps from -80&amp;deg; to 80&amp;deg; (these are white), and the main &lt;a href="http://en.wikipedia.org/wiki/Circle_of_latitude"&gt;circles of latitude&lt;/a&gt; (Equator, Artic/Antarctic Circle, Tropics of Cancer/Capricorn) in red. My first test file also included white lines for several latitudes approaching the poles so I could get an idea of what they looked like in Google Maps... surprise! Because of the problem with infinity, Google Maps doesn't actually SHOW you the whole Earth... any lines I tried to draw further north or south than 85 degrees &lt;a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;q=http%3A%2F%2Fwww.buyog.com%2Fcode%2Fmisc%2Flatlong_bad.xml"&gt;actually &lt;em&gt;broke&lt;/em&gt; the map code&lt;/a&gt;! If you try to click on the links for N 88&amp;deg;, N 89&amp;deg;, or their south equivalents, you'll be shown a line that plots completely off the map! After some trial and error, I've determined that Google's map appears to extend from 85&amp;deg; north to 85&amp;deg; south, omitting much of the Arctic Sea and Antarctica in the process! Admittedly, this is probably no big deal to 99.99999% of the people using Google's amateur cartography tools, but it's interesting to see how Google's &lt;a href="www.google.com/intl/en/jobs/profiles/whygoogle.html"&gt;much-vaunted engineers&lt;/a&gt; tackle an intractable, literally infinite problem space.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5585500967154224027?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5585500967154224027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/mapping-headaches.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5585500967154224027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5585500967154224027'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/mapping-headaches.html' title='Mapping headaches'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6263486656651709969</id><published>2009-05-12T16:30:00.003-05:00</published><updated>2010-01-11T23:44:00.261-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>Sticking to a schedule</title><content type='html'>&lt;p&gt;For the past month or so, I've been following &lt;a href="http://chrisguillebeau.com/3x5/"&gt;Chris Guillebeau's&lt;/a&gt; blog and &lt;a href="http://twitter.com/chrisguillebeau"&gt;Twitter&lt;/a&gt; updates thanks to a link from &lt;a href="http://sethgodin.typepad.com/seths_blog/2009/04/making-a-living-online.html"&gt;Seth Godin&lt;/a&gt;. Even though the stuff these guys talk about has little or nothing to do with my "bread and butter" sources of income (computer and linguistic consulting), I find it fascinating to see how people transforming the collective zeitgeist about what a "career" can and should look like for our generation. Highly inspiring stuff. Case in point: in his recent publishing sensation, &lt;a href="http://chrisguillebeau.com/3x5/overnight-success/"&gt;279 Days to Overnight Success&lt;/a&gt;, Chris suggested that bloggers who, like myself, aspire to extend their personal reach, should establish a regular publication schedule for that blog. So, that's the main point of this post, which I'm going to cross-post to my &lt;a href="http://www.buyog.com"&gt;root&lt;/a&gt; and &lt;a href="http://www.buyog.com/MUGEN"&gt;MUGEN&lt;/a&gt; blogs as well.&lt;/p&gt;

&lt;p&gt;Moving forward, I'm going to try an experiment, and we'll see if I can stick to it. If so, I may expand it out at some point, but this is probably a good place to start:
&lt;ul&gt;
&lt;li&gt;Sundays: I will post something on my &lt;a href="http://www.buyog.com/"&gt;root blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tuesdays: I will post something on my &lt;a href="http://www.buyog.com/code"&gt;code blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fridays: I will post something on my &lt;a href="http://www.buyog.com/MUGEN"&gt;MUGEN blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;do&lt;/strong&gt; have a new post brewing for this blog (next in the &lt;a href="http://www.buyog.com/code/loc/"&gt;Cloning Zelda&lt;/a&gt; series), but it's not ready yet, so it'll most likely wait until next Tuesday to kick off this new schedule.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6263486656651709969?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6263486656651709969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5b-non-stupid-ais.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6263486656651709969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6263486656651709969'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5b-non-stupid-ais.html' title='Sticking to a schedule'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-4822593644707619942</id><published>2009-05-05T14:17:00.005-05:00</published><updated>2009-09-10T13:14:36.112-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 5: Redefining the Sprite classes</title><content type='html'>&lt;p style="font-size: smaller; font-variant: small-caps;"&gt;Previous posts in this series: &lt;a href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html" title="Intro"&gt;Part 1&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html" title="Sprite tiling"&gt;Part 2&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html" title="Map navigation"&gt;Part 3A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html" title="Adding monsters"&gt;Part 3B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html" title="Scaling up / scaling down"&gt;Part 4A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html" title="Adding sounds &amp;amp; music"&gt;Part 4B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-part-4-combat-finally.html"&gt;Part 4C&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Too long since my last post. Moving forward, I'm going to establish a schedule for blog updates, and will work to maintain it. More on that soon.&lt;/p&gt;

&lt;p&gt;As I've &lt;a href="http://www.buyog.com/code/2009/03/cloning-zelda-intermission.html"&gt;mentioned&lt;/a&gt; &lt;a href="http://www.buyog.com/code/2009/04/cloning-zelda-pulse-check.html"&gt;previously&lt;/a&gt;, my sprite classes had become something of a house of cards, which only held together in Firefox and collapsed in every other browser. Clearly, not what I was shooting for.&lt;/p&gt;
&lt;p&gt;I also &lt;a href="http://www.buyog.com/code/2009/04/jsconf-tweets.html"&gt;blogged&lt;/a&gt; last time that I got the chance to speak with &lt;a href="http://higginsforpresident.net/"&gt;Peter Higgins&lt;/a&gt;, the project lead for the &lt;a href="http://www.dojotoolkit.org/"&gt;Dojo Toolkit&lt;/a&gt;, at the &lt;a href="http://www.jsconf2009.com/"&gt;JSConf&lt;/a&gt; developers' conference a few weekends ago. With his help, I've finally managed to wrap my head around how the Dojo class loader works, and have used my newfound knowledge to rebuild the sprite engine for &lt;a href="http://www.buyog.com/code/loc/"&gt;Canvassa&lt;/a&gt;. (whew! that's a lot of links!)&lt;/p&gt;

&lt;p&gt;Bottom line, for the short-attention-span crowd: &lt;a href="http://www.buyog.com/code/loc/part5/sprites.html"&gt;click here&lt;/a&gt; to view the new sprite test harness, which shows off a couple of the new engine's features:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;True class inheritance and dependency resolution (Player and Monster classes are defined in separate files from the base Sprite class)&lt;/li&gt;&lt;li&gt;Animation state and timing "cooked in" to the base classes (press the number keys to see the animations each sprite class defines)&lt;/li&gt;&lt;li&gt;Selective property overriding in derived classes (note the different walking speeds of the sprites)&lt;/li&gt;&lt;li&gt;Should be much more cross-browser compatible (Safari/Chrome/Opera users: please let me know if it doesn't work for you!)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So, the key to Dojo's load system are three commands: &lt;a href="http://api.dojotoolkit.org/jsdoc/1.2/dojo.require"&gt;dojo.require&lt;/a&gt;, &lt;a href="http://api.dojotoolkit.org/jsdoc/1.2/dojo.provide"&gt;dojo.provide&lt;/a&gt;, and &lt;a href="http://api.dojotoolkit.org/jsdoc/1.2/dojo.declare"&gt;dojo.declare&lt;/a&gt;. The way it works is pretty brilliant: when dojo.require is called, the loader code looks to see if the requested class name exists yet in the global namespace. If not, it goes out and looks on the server for a path that matches the requested class's namespace, and if found, a JavaScript file named the same as the class in question. For example, this code:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
  dojo.require("foo.bar.ClassName");
&lt;/pre&gt;

&lt;p&gt;...will start looking in the location of the Dojo module, trying to find a folder named &lt;em&gt;foo&lt;/em&gt;, with a subfolder of &lt;em&gt;bar&lt;/em&gt;. If found, it then looks in that folder for a file named &lt;em&gt;ClassName.js&lt;/em&gt;. If found, it then uses the DOM to dynamically insert a new &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block into the current page's header, referencing the path &lt;em&gt;foo/bar/ClassName.js&lt;/em&gt;. The ClassName.js file, in turn, begins by calling &lt;em&gt;dojo.provide("foo.bar.ClassName")&lt;/em&gt; to indicate its intent, and &lt;em&gt;dojo.declare(...)&lt;/em&gt; to actually define the class. The critical part that Peter helped me understand is that, since this is essentially injecting new code into the header at runtime, the class &lt;strong&gt;won't&lt;/strong&gt; be immediately available... explaining why my code kept blowing up when I tried something like this:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
  dojo.require("loc.Game");
  var game = new loc.Game();
&lt;/pre&gt;

&lt;p&gt;The way to do what I was trying to do, Peter told me, was to leverage the &lt;a href="http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.addOnLoad"&gt;dojo.addOnLoad()&lt;/a&gt; method. This registers a callback function to be executed when all requested classes have been fully loaded. The cool thing about this, Peter told me, was that you could actually chain multiple &lt;em&gt;require()&lt;/em&gt; / &lt;em&gt;addOnLoad()&lt;/em&gt; calls, and Dojo will do the right thing!&lt;/p&gt;

&lt;pre class="brush: js"&gt;
  dojo.require("namespace.Class1");
  dojo.addOnLoad( function() { console.log("Class 1 loaded."); } );

  dojo.require("namespace.Class2");
  dojo.addOnLoad( function() { console.log("Class 2 loaded."); } );

  dojo.require("namespace.Class3");
  dojo.addOnLoad( function() { console.log("Class 3 loaded."); } );
&lt;/pre&gt;

&lt;p&gt;I mean, really: how cool is &lt;strong&gt;THAT&lt;/strong&gt;?!? (answer: &lt;em&gt;very&lt;/em&gt;.)&lt;/p&gt;

&lt;p&gt;So now, armed with the knowledge of how to make Dojo load my classes in the proper order, I'll be able to move forward again. I should be able to leverage most of the old code from parts 2 through 4 of this series, albeit with slight tweaks to fit the new Sprite class model. And therein lies my love for Dojo: it formalizes things I already intuitively know how to do, and makes them work across all potential platforms, without any additional effort on my part. If you're not using Dojo or any other JavaScript framework or toolkit (e.g. &lt;a href="http://mootools.net"&gt;MooTools&lt;/a&gt; / &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; / &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt; / etc.), why the heck not? It makes coding for the web a &lt;strong&gt;much&lt;/strong&gt; more rewarding, and productive, experience.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-4822593644707619942?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/4822593644707619942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5-redefining-sprite.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4822593644707619942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4822593644707619942'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/05/cloning-zelda-part-5-redefining-sprite.html' title='Cloning Zelda, part 5: Redefining the Sprite classes'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1408633824928266958</id><published>2009-04-25T21:38:00.005-05:00</published><updated>2009-06-23T00:54:28.773-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><title type='text'>JSConf Wrap-up and Tweets</title><content type='html'>&lt;p&gt;Had a fantastic weekend at &lt;a href="http://www.jsconf2009.com/"&gt;JSConf&lt;/a&gt; here in DC. Huge thanks to my employer, &lt;a href="http://www.woti.com"&gt;White Oak Technologies&lt;/a&gt;, for sending my team &amp;amp; I.&lt;/p&gt;
&lt;p&gt;Here's a summary of the messages I sent out from Twitter during the conference yesterday and today:&lt;/p&gt;
&lt;ul&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1603560882"&gt; sitting in a packed conference room learning about Objective-J. No idea yet where my coworkers are at&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1603560882"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1603647707"&gt; I suppose I shouldn't be as surprised as I am that so many of the webmonkeys here are Mac people...&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1603647707"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1604410035"&gt;&lt;a target="_blank" href="http://twitter.com/jsconf"&gt;@jsconf&lt;/a&gt; track A has some cool topics, the seating is sub-optimal tho... seating in Track B is way nicer&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1604410035"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1604440277"&gt;&lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/paul_irish')" href="http://twitter.com/paul_irish"&gt;@paul_irish&lt;/a&gt; just gave a great talk on web typography... awesome to see this guy in person after following his blog for months&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1604440277"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1605579286"&gt;Awesome demo of Appcelerator Titanium by &lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/jhaynie')" href="http://twitter.com/jhaynie"&gt;@jhaynie&lt;/a&gt;, gotta find a way to use this..&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1605579286"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1606124566"&gt;Despite a few glitches, the JavascriptMVC pres was pretty good. Not 100% convinced that MVC really "works" for web apps, tho&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1606124566"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1606166884"&gt;urg, stupid phone battery dying from too much wifi usage - and the kicker is that g3 is faster anyway! =P&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1606166884"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1607771630"&gt;&lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/jeresig')" href="http://twitter.com/jeresig"&gt;@jeresig&lt;/a&gt; Awesome talk on web gaming challenges, thanks for sharing!&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1607771630"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1608691868"&gt;&lt;abbr title="Re-tweet"&gt;RT&lt;/abbr&gt; &lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/jhaynie')" href="http://twitter.com/jhaynie"&gt;@jhaynie&lt;/a&gt;: &lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/jeresig')" href="http://twitter.com/jeresig"&gt;@jeresig&lt;/a&gt; presentation was incredibly awesome.&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1608691868"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1615723360"&gt;&lt;a target="_blank" onclick="pageTracker._trackPageview('/exit/to/phiggins')" href="http://twitter.com/phiggins"&gt;@phiggins&lt;/a&gt; rocks. He's a great ambassador for Dojo, and he totally helped me iron out require/declare/provide in the hacker lounge.&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1615723360"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class="result"&gt;
      &lt;span class="msgtxt en" id="msgtxt1615798117"&gt;&lt;a target="_blank" href="http://twitter.com/jsconf"&gt;@jsconf&lt;/a&gt; Thanks for an awesome conference. Already planning on JSConf2010.&lt;/span&gt;
      &lt;a target="_blank" class="lit" href="http://twitter.com/buyog/statuses/1615798117"&gt;[Original Tweet]&lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think the thing I enjoyed the most about this weekend, over and above the awesome food and great demos of cutting-edge advancements in my field, was the opportunity to connect with so many of my peers in the industry at large. It's really easy to get bogged down in the immediacy of the "now", so it's always nice to step back and examine why I do what I do, and why I enjoy it so much.&lt;/p&gt;

&lt;p&gt;Oh, and Peter Higgins, the lead guy behind Dojo, gave me a little personal help in getting the Dojo load system working. So, that next article in my Cloning Zelda series is finally progressing. :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1408633824928266958?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1408633824928266958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/jsconf-tweets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1408633824928266958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1408633824928266958'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/jsconf-tweets.html' title='JSConf Wrap-up and Tweets'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5231954846356547809</id><published>2009-04-24T21:53:00.003-05:00</published><updated>2010-01-11T23:44:00.262-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='_meta_'/><title type='text'>JSConf 2009</title><content type='html'>As I mentioned on &lt;a href="http://www.buyog.com"&gt;my main blog&lt;/a&gt;, I'm attending a local JavaScript conference today &amp;amp; tomorrow with a couple of co-workers. Some great, great stuff today; I tried to tweet about things as they happened.

Yes, &lt;a href="http://www.buyog.com/2009/04/twitterpated.html"&gt;as I mentioned&lt;/a&gt; a few days ago on the root blog, I've finally taken the Twitter plunge. My tweet stream, or whatever you call it, is &lt;a href="http://twitter.com/buyog"&gt;here&lt;/a&gt;, and I've also added a "latest tweet" widget and a twitter icon to the sidebar to the right.

On site-related news, I should have something to post pretty soon, now that my other commitments appear to be winding down a bit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5231954846356547809?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5231954846356547809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/jsconf-2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5231954846356547809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5231954846356547809'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/jsconf-2009.html' title='JSConf 2009'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-4118506477714099856</id><published>2009-04-08T14:49:00.003-05:00</published><updated>2009-09-10T13:14:36.112-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda: pulse check</title><content type='html'>&lt;p&gt;I still haven't posted my next "&lt;a href='http://www.buyog.com/code/loc/'&gt;Cloning Zelda&lt;/a&gt;" article yet; sorry to anyone waiting for that. I have all of the selectable items implemented and working, and had the inventory screen working too, but when I tried to implement the animation on the boomerang, I realized that the frame rate I had chosen, 10 fps, was just too low to make the boomerang work satisfactorily. Link was also slow to respond to keyboard input, because I was responding to multiple keypress events instead of having him walk continuously until the arrow key was released. I've fixed that, but it's led to some wall collision problems that I haven't resolved yet. Grr.&lt;/p&gt;

&lt;p&gt;Sooo... "back to the drawing board" in some sense. Bumping the frame rate up to a respectable level fixed the boomerang issue, and let me implement the "flashing" effect for thrown swords (they were plain in &lt;a href="http://www.buyog.com/code/loc/part4/"&gt;Part 4&lt;/a&gt;), but now the player and enemy movements are way too fast, looking like some feudal &lt;a href="http://en.wikipedia.org/wiki/Marvin_the_Martian"&gt;Marvin the Martian&lt;/a&gt; knockoff. The solution is to rewrite the movement code for the &lt;em&gt;Player&lt;/em&gt; and &lt;em&gt;Monster&lt;/em&gt; classes; &lt;em&gt;Monster&lt;/em&gt; isn't bad because it was built from the ground up with multiple-animation support built in, but animations were grafted onto the &lt;em&gt;Player&lt;/em&gt; class quite a bit later, so it's proving to be pretty much a rewrite. Ugh.&lt;/p&gt;

&lt;p&gt;Add to that the big "&lt;a href='http://www.buyog.com/MUGEN/2009/04/scruffyversary-2009.html'&gt;Scruffyversary&lt;/a&gt;" event my &lt;a href="http://www.scruffydragon.com" title="Scruffy Dragon Productions"&gt;MUGEN development team&lt;/a&gt; is throwing this month, and the looming deadlines for my next-to-last (hopefully anyway) semester of grad school, and you've the the perfect storm for blogging delays.&lt;/p&gt;

&lt;p&gt;Taking all of the above as a given, may I humbly offer a solution: since I publish all of my content via &lt;a href="http://en.wikipedia.org/wiki/RSS"&gt;RSS&lt;/a&gt; through &lt;a href="http://www.feedburner.com"&gt;FeedBurner&lt;/a&gt;, I'd suggest just throwing my feed URL (&lt;a href="http://feeds2.feedburner.com/PalagpatCoding"&gt;http://feeds2.feedburner.com/PalagpatCoding&lt;/a&gt;) in your feed reader of choice. That way when I update, you'll get the new post auto-magically, without having to hit my site directly and be disappointed when there's nothing new to read.&lt;/p&gt;

&lt;p&gt;If you don't yet know about &lt;a href="http://en.wikipedia.org/wiki/Aggregator"&gt;feed aggregation&lt;/a&gt;, you really owe it to yourself to learn. It'll save you a LOT of time if you follow even a fraction as many web sites as I do, and in the world we live in, who wouldn't want more time?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-4118506477714099856?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/4118506477714099856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/cloning-zelda-pulse-check.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4118506477714099856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/4118506477714099856'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/04/cloning-zelda-pulse-check.html' title='Cloning Zelda: pulse check'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7603503214496409421</id><published>2009-03-18T20:47:00.004-05:00</published><updated>2009-09-10T13:14:36.112-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, intermission</title><content type='html'>&lt;p&gt;I'm hard at work on Part 5, and I hope to get it done soon so I can put more effort into blogging about it.&lt;/p&gt;

&lt;p&gt;Meanwhile, a couple of notes:
&lt;img src="http://www.buyog.com/code/images/loc_swordFail.png" alt="sprite problems" style="float:right"/&gt;
&lt;ul&gt;
&lt;li&gt;In making some changes to the image format for Part 5, I accidentally broke the sword sprites in Part 4. &lt;span style="font-size:smaller; font-variant:small-caps"&gt;(Oops!)&lt;/span&gt; It's now fixed.&lt;/li&gt;
&lt;li&gt;I added a new index page of sorts to keep track of the Zelda/Canvassa progress; it's &lt;a href="http://www.buyog.com/code/loc"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;That page also includes a revised tasklist for "Phase 1" of my plans for Canvassa; dungeons and bosses would be a huge undertaking over and above what I've already bitten off, and I'm not yet sure that committing to doing it is wise for my sanity's sake.&lt;/li&gt;
&lt;li&gt;I just discovered yesterday that my dumb CSS-based layout &lt;em&gt;still&lt;/em&gt; doesn't render right on all browsers/window sizes. I'm about &lt;strong&gt;&lt;em&gt;THIS&lt;/em&gt;&lt;/strong&gt; close to just rewriting the whole page template using HTML tables and being done with it.&lt;/li&gt;
&lt;li&gt;Yes, I know Part 4 doesn't work in IE or Chrome. I wouldn't be surprised if I broke it in Safari and Opera, too. :( All I can say is, I'm working on it.*&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p style="font-size: small;"&gt;&lt;em&gt;* The culprit seems to be JS-itis... I've been putting each new class heirarchy in its own JavaScript file, but they're all messily interrelated and all live in the global namespace, so it goes BOOM in every other browser besides Firefox 3. &lt;strong&gt;(but it works fine in FF!)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'm considering using Dojo.require() to keep track of loading order and dependencies for me, but on the other hand, maybe I ought to just slap the whole thing into a single .js file and be done with it. Still pondering pros and cons on that one.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7603503214496409421?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7603503214496409421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/03/cloning-zelda-intermission.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7603503214496409421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7603503214496409421'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/03/cloning-zelda-intermission.html' title='Cloning Zelda, intermission'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6606142195527427620</id><published>2009-03-14T23:47:00.004-05:00</published><updated>2009-09-10T13:14:36.113-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 4C: Combat (finally!)</title><content type='html'>&lt;p style="font-size: smaller; font-variant: small-caps;"&gt;Previous posts in this series: &lt;a href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html" title="Intro"&gt;Part 1&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html" title="Sprite tiling"&gt;Part 2&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html" title="Map navigation"&gt;Part 3A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html" title="Adding monsters"&gt;Part 3B&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html" title="Scaling up / scaling down"&gt;Part 4A&lt;/a&gt; | &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html" title="Adding sounds &amp;amp; music"&gt;Part 4B&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, a technical note: I recently discovered that this blog was completely unreadable in Internet Explorer. I've been using &lt;a href="http://www.getfirefox.com"&gt;Firefox&lt;/a&gt; almost exclusively for some time now, but was at a bit of a loss to explain why this was happening -- anyway, turns out it was because I was using a CSS file that specifies different rendering layouts for different browser platforms (i.e. smartphones, etc) using the @media tag -- &lt;a href="http://www.howtocreate.co.uk/tutorials/css/mediatypes"&gt;which IE ignores&lt;/a&gt;! Oops. Anyway, tonight I finally tracked it down with the help of the cool &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419"&gt;IE Tab&lt;/a&gt; add-on for Firefox, and this blog is once again readable to users of &lt;a href="http://toastytech.com/evil/uf.html"&gt;Microsoft's&lt;/a&gt; &lt;a href="http://www.erikarathje.ca/blog/2006/05/internet_explorer_is_the_root_1.html"&gt;wacky&lt;/a&gt; &lt;a href="http://jrwren.wrenfam.com/blog/2006/10/16/internet-explorer-is-truly-evil/"&gt;browser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, to the subject at hand: I've decided that I'm biting off entirely too much with the &lt;a href="http://www.buyog.com/code/2009/01/zelda-task-list.html"&gt;original task distribution&lt;/a&gt; I came up with for this Javascript Zelda-cloning effort. Part 3 ended up having a &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html"&gt;Part 3A&lt;/a&gt; and a &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3b-monster-think.html"&gt;Part 3B&lt;/a&gt;, and Part 4 has ended up as 3 sub-sections: &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4a-size-isnt.html"&gt;Part 4a&lt;/a&gt; dealt with the issue of game size, since I actually prefer playing it in its &lt;a href="http://www.buyog.com/code/loc/part4/index.html"&gt;original size&lt;/a&gt;, but my son likes playing it in the &lt;a href="http://www.buyog.com/code/loc/part4/index2x.html"&gt;double-sized version&lt;/a&gt; I originally started with. &lt;a href="http://www.buyog.com/code/2009/02/cloning-zelda-part-4b-now-hear-this.html"&gt;Part 4b&lt;/a&gt; came about because I was tired of the game being silent and I discovered &lt;a href="http://schillmania.com/projects/soundmanager2"&gt;a way to implement sound&lt;/a&gt; pretty easily. The original goal of Part 4, though, was about making the combat system work. This is now, for the most part, done; at least I'm ready to blog about it and move on to something else.&lt;/p&gt;

&lt;p&gt;So, what did I do to finish part 4? Several things:
&lt;ol&gt;
&lt;li&gt;Added player hearts / hit points&lt;/li&gt;
&lt;li&gt;Added player's sword (press the A button, or the Z key on your keyboard)&lt;/li&gt;
&lt;li&gt;Added sword projectiles when health is full&lt;/li&gt;
&lt;li&gt;Added collision detection, so monsters can hurt the player, and the player can hurt the monsters.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;

&lt;p&gt;Those were the main points. But in order to make them work reasonably well, I had to also implement several other things:
&lt;ol&gt;
&lt;li&gt;Added a basic animation state system to the player class, since he now has several different possible animation states (walking, swinging his sword, getting hit, dying, etc)&lt;/li&gt;
&lt;li&gt;Added a new "game over" state to the game, for when the player dies&lt;/li&gt;
&lt;li&gt;That meant implementing the game's text system as well, because I didn't feel like hacking something temporary that would get replaced soon; my test harness for the text system is &lt;a href="http://www.buyog.com/code/loc/part4/font.html"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Started the basics of the item system, since Link needed a way to get (and throw) the sword, plus he needed to be able to pick up hearts dropped by the monsters he killed in order to replenish his health. The basics of the item heirarchy are in the new &lt;a href="http://www.buyog.com/code/loc/part4/items.js"&gt;items.js&lt;/a&gt; class.&lt;/li&gt;
&lt;li&gt;Plus, the aforementioned scaling and sound updates that came in with parts 4A and 4B.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;

&lt;p&gt;The most interesting part of all of this new stuff is probably the collision detection. I implemented it by adding a new &lt;span style="font-family: monospace"&gt;doHitTests()&lt;/span&gt; method to the main game loop in &lt;a href="http://www.buyog.com/code/loc/part4/game.js"&gt;game.js&lt;/a&gt;, beautifully rendered here using Alex Gorbatchev's awesome &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter&lt;/a&gt; tool:

&lt;pre class="brush: js"&gt;
this.main = function() {
    // update monster positions (but only if on the overworld/dungeon screens)
    if (this.currentMode == 0 || this.currentMode == 2) {
        for each (var enemy in this.enemies) {
            enemy.think();
        }

        // move all active projectiles
        for each (var proj in this.projectiles) {
            proj.updatePosition()
        }

        // do sprite collision tests
        this.doHitTests();
    }

    // draw everything
    this.drawSprites();
}

this.doHitTests = function() {
    // we only care about collision detection if in overworld or dungeon modes
    if (this.currentMode == 0 || this.currentMode == 2) {
        // do sprite collision tests
        var hits = game.hitTest(player.pos.x, player.pos.y, 12,12);

        // check to see if any monsters are touching the player;
        // if so, he's hurt to the tune of their relative strength
        for each (var attacker in hits[0]) {
            if (attacker.canAttack()) {     // ignore is monster is stunned or dying
                player.getHit(attacker.strength);
                break;
            }
        }

        // see if there is anything in this area to pick up
        for each (var item in hits[1]) {
            player.getItem(item);
            delete game.items[item._index];
        }

        // if there are any projectiles in play, see if they hit anything, too
        for each (var proj in this.projectiles) {
            // player-owned projectiles can only damage enemies, and vice-versa,
            // so check projectile type against hit target type
            if (proj.owner == player) {
                hits = game.hitTest(proj.pos.x, proj.pos.y, proj.width,proj.height);

                for each (var enemy in hits[0]) {
                    enemy.getHit(proj.power);
                }
            }
        }

        // note: player class handles attack collision detection internally
        // by making a call to game.hitTest(x,y,w,h)
    }
}

this.hitTest = function(x,y,w,h){
    // check all active monsters to see if they are within the
    // specified area; return a list of any that are found there
    var enemies = []; projectiles = []; items = [];
    for each (var enemy in this.enemies) {
        var dx = Math.abs(x-enemy.pos.x);
        var dy = Math.abs(y-enemy.pos.y);
        if (dx &lt;= w &amp;&amp; dy &lt;= h) {
            enemies.push(enemy);
        }
    }

    for (var i in this.items) {
        var item = this.items[i];
        item._index = i;
        var dx = Math.abs(x-item.pos.x);
        var dy = Math.abs(y-item.pos.y);
        if (dx &lt;= w &amp;&amp; dy &lt;= h) {
            items.push(item);
        }
    }


    return [enemies,items];
}
&lt;/pre&gt;

&lt;p&gt;Not too much more to say here. The AI of some of the monsters (most notably the tectites and peahats) is still pretty wonky, and none of the monsters have projectile attacks yet, but that'll be easy enough to adapt from the sword projectiles we gave to the player in this update. The game is finally getting pretty interesting to play, and it's time to move on.&lt;/p&gt;

&lt;p&gt;Check out the latest version of the game here: &lt;a href="http://www.buyog.com/code/loc/part4/index.html"&gt;small version&lt;/a&gt; or &lt;a href="http://www.buyog.com/code/loc/part4/index2x.html"&gt;large version&lt;/a&gt;

&lt;p&gt;Next time, we'll expand on the Items class heirarchy and get the player's inventory system working.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6606142195527427620?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6606142195527427620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/03/cloning-zelda-part-4-combat-finally.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6606142195527427620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6606142195527427620'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/03/cloning-zelda-part-4-combat-finally.html' title='Cloning Zelda, part 4C: Combat (finally!)'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-2679065238037438280</id><published>2009-02-27T23:12:00.007-05:00</published><updated>2009-09-10T13:14:36.113-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 4B: Now hear this!</title><content type='html'>&lt;p&gt;A few weeks ago I discovered &lt;a href="http://schillmania.com/projects/soundmanager2"&gt;SoundManager2&lt;/a&gt;, a JavaScript library that uses a tiny, invisible Flash applet to enable audio playback directly via JavaScript! Awesome! But I had a heck of a time actually making the durn thing &lt;strong&gt;work&lt;/strong&gt; with my data files.&lt;/p&gt;

&lt;p&gt;First, I grabbed some WAV files for the original Legend of Zelda sound effects and music from &lt;a href="http://noproblo.dayjo.org/ZeldaSounds/"&gt;a great LoZ resource site&lt;/a&gt; run by a good soul named HelpTheWretched (&lt;em&gt;"Aren't online monikers fun?"&lt;/em&gt; says the guy who named &lt;a href="http://www.websters-online-dictionary.org/translation/buyog"&gt;himself&lt;/a&gt; after a Philippine bumblebee). I then used &lt;a href="http://cdexos.sourceforge.net/"&gt;CDEX&lt;/a&gt; and its bundled LAME mp3 encoder to convert the WAV files to mp3 format. (this is a limitation of the current version of SoundManager: it can only play mp3s. No wav, no aac, no ogg. Bummer.) Finally tonight, after fiddling with SM2's troubleshooting page for a while and utilizing my mad copy/paste-fu skills, I got it to work! So if you go back to either of the Part 4 versions of the game (&lt;a href="http://www.buyog.com/code/loc/part4/"&gt;1x&lt;/a&gt; or &lt;a href="http://www.buyog.com/code/loc/part4/index2x.html"&gt;2x&lt;/a&gt;), you'll now hear the overworld music, as well as the slash of your sword!&lt;/p&gt;

&lt;p&gt;As for the rest of the stuff that's actually &lt;em&gt;supposed&lt;/em&gt; to be part of Part 4, namely the monster-killing stuff: I've fiddled with a couple of different options for collision testing, none of which I'm really very happy with yet. At first I thought maybe the getImageData() method on the Canvas 2d &lt;em&gt;context&lt;/em&gt; object would be useful, and even roughed up a test to poll the sprite canvas for image data. But even though it would be pretty efficient at telling me about collisions in a particular coordinate location, I'd still have to back and figure out exactly &lt;strong&gt;&lt;em&gt;what&lt;/em&gt;&lt;/strong&gt; sprites those pixels represented. So I may just have to stick with a close approximation based on sprite sizes, positions, and velocities. I should have something worked out by next week.&lt;/p&gt;

&lt;p style="font-size:smaller;"&gt;Man, if "Part 3" had 2 parts, and Part 4 looks like it's going to have 3... sheesh, I think I'm going to have to rethink &lt;a href="http://www.buyog.com/code/2009/01/zelda-task-list.html"&gt;my original task list&lt;/a&gt;... =P&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-2679065238037438280?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/2679065238037438280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/02/cloning-zelda-part-4b-now-hear-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2679065238037438280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/2679065238037438280'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/02/cloning-zelda-part-4b-now-hear-this.html' title='Cloning Zelda, part 4B: Now hear this!'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-1786873281586264913</id><published>2009-02-24T22:40:00.004-05:00</published><updated>2009-09-10T13:14:36.113-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 4A: Size is(n't?) Everything</title><content type='html'>As many of my half dozen readers have correctly deduced, Part 4 was another case of me biting off more than I could chew. I'm not quite done with what I set out to accomplish in this part, hence the "4a," but here's what I've done so far:
&lt;ul&gt;
&lt;li&gt;Implemented sword and heart inventory for player&lt;/li&gt;
&lt;li&gt;Added the ability to swing your sword (alas, it doesn't hurt the monsters yet... but then again, they don't hurt you yet, either)&lt;/li&gt;
&lt;li&gt;Added initial "spawn" state to enemies&lt;/li&gt;
&lt;li&gt;Coded up the scaling functionality that I've been building&lt;/li&gt;&lt;/ul&gt;

The full writeup will come soon; for now, check out part 4a: see &lt;a href="http://www.buyog.com/code/loc/part4/index.html"&gt;1x size&lt;/a&gt;, &lt;a href="http://www.buyog.com/code/loc/part4/index2x.html"&gt;2x size&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-1786873281586264913?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/1786873281586264913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/02/cloning-zelda-part-4a-size-isnt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1786873281586264913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/1786873281586264913'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/02/cloning-zelda-part-4a-size-isnt.html' title='Cloning Zelda, part 4A: Size is(n&apos;t?) Everything'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5508897234002964636</id><published>2009-01-22T19:57:00.011-05:00</published><updated>2009-09-10T13:14:36.113-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 3B: Monster-think</title><content type='html'>&lt;p&gt;As I mentioned &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-part-3a-coordinated.html"&gt;last time&lt;/a&gt;, part 3 ended up being too much work to describe all in a single post. Here's part B.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.buyog.com/code/loc/web/part3b.png" alt="wandering armos" style="float:left; padding: 0 10px 10px 0"/&gt;When I worked up the map schema in part 2, I had to decide how to handle the non-static portions of the scenery: walls that can be blown up, trees that can be burned, and statues that can get up and walk around. We'll deal with the walls and trees in a subsequent entry, but the statues &lt;img src="http://www.buyog.com/code/loc/web/armos0.png" alt="armos statue"/&gt;, called Armos, were better treated as monsters since they can be woken up (&lt;img src="http://www.buyog.com/code/loc/web/armos1.png" alt="live armos"/&gt;), move around, attack, get killed, and respawn when you come back to the screen later (a burned bush or exploded wall, on the other hand, stays that way for the rest of the game). So I figured it was time to decide how to deal with the game's &lt;a href="http://en.wikipedia.org/wiki/Sprite_(computer_graphics)"&gt;sprites.&lt;/a&gt;&lt;/p&gt;

&lt;p style="clear:both"&gt;As I mentioned in &lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html"&gt;part 2&lt;/a&gt;, the original implementation of the game drew the map and Link on a single canvas, which had to be completely repainted for every game tick. One way around this is to use multiple Canvas elements, layered one on top of the other:&lt;/p&gt;
&lt;img src="http://www.buyog.com/code/loc/web/layers.png" alt="two overlapping canvas layers"/&gt;

&lt;p&gt;The "background" canvas gets painted first, on the bottom, then the game's sprites are all painted transparently onto the sprite canvas &lt;em&gt;above&lt;/em&gt; the background, so it truly only needs to be repainted when it changes. Accomplishing this in HTML code is as simple as defining a CSS selector that applies to all canvas tags, like so:&lt;/p&gt;
&lt;pre class="brush: js"&gt;
canvas {
  border: 6px double black;
  position: absolute;
  top: 20px;
  left: 20px;
}
&lt;/pre&gt;

&lt;p&gt;The canvas tags themselves are declared one right after the other, bottom layer first then working upwards (this keeps them in the proper z-order):&lt;/p&gt;
&lt;pre class="brush: js"&gt;
&amp;lt;canvas id="map" width="512" height="480"&amp;gt;&amp;lt;/canvas&amp;gt;
&amp;lt;canvas id="sprites" width="512" height="480"&amp;gt;&amp;lt;/canvas&amp;gt;
&lt;/pre&gt;

&lt;p&gt;With the canvas layers properly set up, I modified the game code to paint each layer only when appropriate: redrawing the background layer when it changes, and redrawing the sprite layer on every iteration through the main game loop. That loop, then, becomes responsible for painting Link, the monsters, and any items/loot lying around on the ground. I usually try to do things in an object-oriented way if at all possible, so the map, player, and enemy classes each take care of painting themselves. That makes the main game loop's "redraw" section quite succinct:&lt;/p&gt;
&lt;pre class="brush: js"&gt;
this.drawSprites = function(){
   ...
    // draw any enemies
    if (this.enemies) {
        for (var i=0; i&amp;lt;this.enemies.length; i++) {
            this.enemies[i].draw(spriteCanvas);
        }
    }

    // draw link
    player.draw(spriteCanvas);
    ...
}
&lt;/pre&gt;
&lt;p&gt;(Incidentally, I am indebted to the sprite gallery at &lt;a href="http://www.zeldadungeon.net/"&gt;ZeldaDungeon.net&lt;/a&gt; for most of my enemy sprites, although I did rip a few from an old NES emulator I had lying in a musty old corner of my hard drive). Aside from a few other bits of code to take care of things like the game header, that's the heart of the game.drawSprites() method, which is one-half of the game's main program loop (we'll talk about the other half in a minute).&lt;/p&gt;

&lt;p&gt;As I noted in the last paragraph, the game is now structured to include an array of "enemy" objects at all times. This array gets re-initialized whenever Link enters a new screen, based on the data encoded in the &lt;a href="http://www.buyog.com/code/loc/part3/gameData.js"&gt;gameData structure&lt;/a&gt; for each map screen. Here, for example, is part of the entry for overworld map screen 4,3 (the one shown in the first image in this post):&lt;/p&gt;
&lt;pre class="brush: js"&gt;
enemies: [
    {type:'armos',color:0,position:{x:40,y:72}},
    {type:'armos',color:0,position:{x:72,y:72}},
    {type:'armos',color:0,position:{x:104,y:72}},
    {type:'armos',color:0,position:{x:40,y:104}},
    {type:'armos',color:0,position:{x:72,y:104}},
    {type:'armos',color:0,position:{x:104,y:104}},
    {type:'leever',color:1,position:{x:72,y:40}},
    {type:'leever',color:1,position:{x:104,y:40}},
    {type:'leever',color:1,position:{x:152,y:40}},
    {type:'leever',color:1,position:{x:152,y:72}},
]
&lt;/pre&gt;
&lt;p&gt;The gameData definition for monsters consists of three parts: a type, a color, and a starting position. The type indicates the type of monster object to be spawned, and color and position are passed along to its constructor so that it knows how and where to draw itself when asked to do so (many enemy types have a a red/orange and a blue "subspecies", as it were; the color attribute specifies which to draw). The Game class contains a large switch() block that uses the &lt;em&gt;type&lt;/em&gt; value to determine which Enemy subclass to instantiate.&lt;/p&gt;

&lt;p&gt;Yes, enemy subclasses. When you consider all of the different types of monster in the Zelda overworld (and even in the dungeons), there are shared traits. For instance, some monsters (namely Octorocs, Moblins, and Lynels) can throw things at you (rocks, arrows, and swords, respectively): it makes sense to define an &lt;a href="http://en.wikipedia.org/wiki/Abstract_type"&gt;abstract base class&lt;/a&gt;, let's call it "Thrower", for enemies that throw things. We can then put the specific code that implements the throwing into the base class, and just override the function that draws the sprites for each respective type of enemy derived from that class. (&lt;em&gt;note&lt;/em&gt;: I am using the excellent Javascript library &lt;a href="http://dojotoolkit.org/"&gt;Dojo&lt;/a&gt; to handle my classes now; it does all of the heavy lifting for me in terms of polymorphism, class inheritance, etc.)&lt;/p&gt;
&lt;pre class="brush: js"&gt;
dojo.declare("Enemy", null, {
    constructor: function(position, color){},
    draw: function(ctx){},
    canMove: function(direction){},
    move: function(direction){},
    think: function(){}
});

dojo.declare("Thrower", Enemy, {
    // (moblins, octorocs, lynels)
    attack: function(){ // todo: launch projectile object }
});

dojo.declare("Octoroc", Thrower, {
    constructor: function(position, color){ // override base class to store correct sprite drawing info, etc }
});
&lt;/pre&gt;

&lt;p&gt;I omitted a lot of the implementation details in the above example; indeed, not everything is even implemented yet! Nevertheless, the basic framework is now in place so that enemies appear in their proper places on each map screen, and all know how to move, more or less: I haven't yet fixed the Diggers subclass for Leevers and Zolas so that they go below the ground/water and pop up in a new position, nor have I implemented the pseudo-"jumping" movement that Tectites use. Both of these enemy subtypes just use the base type's movement algorithm at the moment. Likewise, I also haven't implemented the attack() method on the Thrower subclass; that's part of what I'll be doing in Part 4 of this series. But at the very least, all enemies can take advantage of the think() method, which we call from the main game loop (see? Told you I'd talk about the other half), which I can now show in its entirety:&lt;/p&gt;
&lt;pre class="brush: js"&gt;
this.main = function() {
    // update monster positions
    if (this.enemies) {
        for (var i=0; i&amp;lt;this.enemies.length; i++) {
            this.enemies[i].think();
        }
    }

    // draw everything
    this.drawSprites();
}&lt;/pre&gt;

&lt;p&gt;If you'd like to look at the implementation of the Enemy class and its many subclasses, they're all contained in the &lt;a href="http://www.buyog.com/code/loc/part3/enemies.js"&gt;enemies.js&lt;/a&gt; script file (The updated game.js is &lt;a href="http://www.buyog.com/code/loc/part3/game.js"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;So, now we have enemies, and they know (kinda-sorta) how to move around. The game is finally (almost) starting to get interesting to play, now: when my son saw it, it engrossed him for 15 minutes or more as he walked around exploring the whole overworld and all of its ecosystems. Feel free to do the same, &lt;a href="http://www.buyog.com/code/loc/part3" title="The Legend of Canvassa, Part 3: Monsters"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next time, we'll finally get around to giving Link a sword and the ability to swing it. He'll need it, because we're also going to implement hit points and the ability to kill (and be killed)!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5508897234002964636?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5508897234002964636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-part-3b-monster-think.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5508897234002964636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5508897234002964636'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-part-3b-monster-think.html' title='Cloning Zelda, part 3B: Monster-think'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-3157603352140152360</id><published>2009-01-19T10:34:00.013-05:00</published><updated>2009-09-10T13:14:36.114-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 3A: Coordinated</title><content type='html'>&lt;p&gt;&lt;img src="http://www.buyog.com/code/loc/web/part3.png" alt="positioning Link on the map" style="float:left; padding: 0 10px 10px 0;"/&gt;&lt;a href="http://www.buyog.com/code/2009/01/cloning-zelda-day-2.html"&gt;Last time&lt;/a&gt; I said we'd be fixing the walk code so that Link can't walk through walls/water/etc anymore, and adding in the missing &lt;img src="http://www.buyog.com/code/loc/web/armos0.png" alt="armos statue"/&gt; Armos statues to the map. I should've known that was a bit ambitious to tackle both in a single chunk, and indeed it was. So Part 3 will be split into two sections; this is the first.&lt;/p&gt;

&lt;p&gt;The first thing I needed to figure out was how to restrict Link's movement on the map. I had a vague idea involving the map data's use of tile coordinates to the &lt;a href="http://www.buyog.com/code/loc/res/overworld_tiles.png"&gt;overworld tile image&lt;/a&gt; I used... I tried to keep all of the "walkable" tiles in that first column, but since I used decimal digits instead of hex digits to address the tiles, I was limited to a 10-tile column, which meant I would be leaving out the dock and stairs tiles if that was my only criteria. Nevertheless, I tried to keep all of the walkable tiles confined to a small space on the image, and figured I'd deal with it in the code.&lt;/p&gt;

&lt;p&gt;The code side, in fact, turned out to be fairly straightforward: I added a new routine to the mapScreen class to report on whether a particular (x,y) space on the map screen is walkable. I called it, oddly enough, cellIsWalkable(). It was pretty straightforward... given the x,y coordinates to test, I first had to figure out the 16x16 cell containing those coordinates by dividing x and y each by 16. Once I knew the specific cell containing the target point, I could then check the tile it was using to see if it met "walkable" criteria. &lt;a href="http://www.buyog.com/code/loc/part3/map.js"&gt;Here's&lt;/a&gt; the updated map.js file with the new function.&lt;/p&gt;

&lt;p&gt;In the process of coding up this whole movement-restriction thing, I realized something else: the original game isn't strictly top-down. In a kind of a stab at a pseudo-isometric interface, Link can kind of "sidle up" to unwalkable cells from below, like so:&lt;/p&gt;

&lt;img src="http://www.buyog.com/code/loc/web/overlap.png" alt="Link overlapping a rock"/&gt;&lt;p/&gt;

&lt;p&gt;As you can see, it lends a bit of a sense of layering to the game, enhancing the illusion of a 3-dimensional playing field. I decided the best way to accomplish this overlap was to relocate the main y-position from the top of Link's head, to his middle. Then all "can I go up?" type requests are made from that center point--not from the top of his head--and the overlap works as it should.&lt;/p&gt;

&lt;p&gt;Once I'd relocated Link's y-position, I decided to move his x-position to the sprite's center as well, to better handle movement restriction along the x-axis (I wanted to be able to block Link from walking into walls on both his sides, not just on the left). I then modified the cellIsWalkable() tests along the x-axis to account for an 8-pixel offset on either side, and the work was done (Refer to the image at the top of this entry to see how the axis relocation was done). Or, refer to the modified &lt;a href="http://www.buyog.com/code/loc/part3/player.js"&gt;player.js&lt;/a&gt; file for more details of how it all fits together.&lt;/p&gt;

&lt;p&gt;I'll get to monsters in the next entry.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-3157603352140152360?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/3157603352140152360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-part-3a-coordinated.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3157603352140152360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/3157603352140152360'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-part-3a-coordinated.html' title='Cloning Zelda, part 3A: Coordinated'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-6118223771178245408</id><published>2009-01-13T01:00:00.002-05:00</published><updated>2009-09-10T13:14:36.114-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Zelda task list</title><content type='html'>&lt;p&gt;Working on part 3 of the "Cloning Zelda" project, and since I don't Twitter, I need a place to put this "to do" list:&lt;/p&gt;

&lt;em&gt;Part 3: Monsters&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Implement class hierarchy for all overworld monsters (done)&lt;/li&gt;
&lt;li&gt;Encode monster spawn location info in the game's defining data structure (in progress)&lt;/li&gt;
&lt;li&gt;Finish map movement restrictions: no more "boss mode" movement (in progress)&lt;/li&gt;
&lt;/ul&gt;

&lt;em&gt;Part 4: Fight!&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Implement player hit points&lt;/li&gt;
&lt;li&gt;Implement player sword attack&lt;/li&gt;
&lt;li&gt;Implement monster:
&lt;ul&gt;&lt;li&gt;artificial intelligence,&lt;/li&gt;
&lt;li&gt;collision detection,&lt;/li&gt;
&lt;li&gt;hit points / damage,&lt;/li&gt;
&lt;li&gt;and projectile attacks&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;

&lt;em&gt;Part 5: Grottos and non-player characters&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Implement grotto entrances/exits&lt;/li&gt;
&lt;li&gt;Implement "conversation" mode (so old men can give us swords and such)&lt;/li&gt;
&lt;/ul&gt;

&lt;em&gt;Part 6: Currency and stores&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Implement rupees (and make enemies drop them)&lt;/li&gt;
&lt;li&gt;Implement inventory screen / item selection&lt;/li&gt;
&lt;li&gt;Implement stores&lt;/li&gt;
&lt;/ul&gt;

&lt;em&gt;Part 7: Map interactivity&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Implement bush-burning&lt;/li&gt;
&lt;li&gt;Implement wall-bombing&lt;/li&gt;
&lt;li&gt;Implement hidden grotto entrances (under bushes, behind walls, and the waterfall)&lt;/li&gt;
&lt;li&gt;Implement whistle-warping&lt;/li&gt;
&lt;li&gt;Implement Lost Woods and Lost Hills special map movements&lt;/li&gt;
&lt;li&gt;Implement the Secret Pond (Dungeon 7 entrance)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the above stuff is done (&lt;em&gt;IF&lt;/em&gt; I ever get it all done!), I'll be at a reasonable transition point: the Overworld will be all but finished, and I'll be ready to decide if I want to tackle the dungeons or not. We'll see how long it takes me to do all of this (and any other things I'm forgetting, too)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-6118223771178245408?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/6118223771178245408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/zelda-task-list.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6118223771178245408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/6118223771178245408'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/zelda-task-list.html' title='Zelda task list'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-5810572384946621664</id><published>2009-01-09T00:21:00.007-05:00</published><updated>2009-09-10T13:14:36.114-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda, part 2: Tile thing</title><content type='html'>&lt;img src="http://www.buyog.com/code/loc/web/day2.png" alt="Cloning Zelda, Part 2"/&gt;

&lt;p&gt;&lt;a href="http://www.buyog.com/code/2008/12/cloning-zelda-in-javascript-day-1.html"&gt;Last time&lt;/a&gt;, I talked about how I had started working on a clone of the Legend of Zelda in a pure-JavaScript aesthetic. When I started researching and brainstorming solutions to the challenge of hit detection, not to mention the game's overall memory footprint, I realized I had a problem. &lt;a href="http://www.buyog.com/code/loc/part1/index.html"&gt;My first stab at the game&lt;/a&gt; used a single, huge (4096x1408) &lt;a href="http://www.buyog.com/code/loc/res/overworld.png"&gt;PNG image&lt;/a&gt; (downloaded from &lt;a href="http://ian-albert.com/misc/zelda.php"&gt;here&lt;/a&gt;, forgot to mention that last time) as its map, and I kept track of an offset to the current screen's position on the huge image, which the main program loop would repaint on the canvas &lt;em&gt;every single game tick&lt;/em&gt;! Eeek!&lt;/p&gt;

&lt;p&gt;Needless to say, upon reflection, that looked like a &lt;em&gt;really&lt;/em&gt; bad idea. So I went back to the drawing board, and came up with several design considerations:
&lt;ol&gt;
  &lt;li&gt;Only repaint the background image when it changes (not every game tick!)&lt;/li&gt;
  &lt;li&gt;Use two canvas layers to separate background from sprites (so player and enemy movement won't trigger a background redraw)&lt;/li&gt;
  &lt;li&gt;Use a "tile" approach to limit image size in memory&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;

&lt;div style="float:right; text-align: center;"&gt;&lt;img src="http://www.buyog.com/code/loc/res/overworld_tiles.png" alt="zelda overworld tiles"/&gt;&lt;br/&gt;&lt;caption&gt;Overworld map tiles*&lt;/caption&gt;&lt;/div&gt;

&lt;p&gt;So, armed with my trusty copy of &lt;a href="http://www.jasc.com"&gt;Paint Shop Pro 7&lt;/a&gt;, I started slicing up the map. What I discovered was that the game overworld uses a surprisingly sparse number of tiles to do its job...  in fact, these 79 tiles cover all the bases! As I said before, the full map of Hyrule is 4096 pixels wide by 1408 pixels high. We can reproduce the whole thing by using a 2-dimenional array of 256x88 tiles, 16 pixels square. I chose to go one step further, subdividing the map into individual screens, and each screen into its component tiles. This gave me a 3-level map structure:
&lt;ul&gt;
&lt;li&gt;1 map of 4096x1408 pixels&lt;/li&gt;
&lt;li&gt; = a 16x8 matrix of map screens,&lt;/li&gt;
&lt;li&gt; each of which = a 16x11 matrix of 16x16 tiles&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;Now came the long &amp; tedious part: encoding the map as a data structure! I let the above structure inform my design decisions, creating a Map class with: a &lt;em&gt;current&lt;/em&gt; property to contain an x/y pair representing the currently visible screen within the map, and a 16x8 two-dimensional array containing MapScreen objects&lt;/li&gt;. Each MapScreen object knows its (x,y) position within the larger map, and contains a 16x11 array of cells, each an (x,y) coordinate pair representing that cell's source tile in the global "tiles" image. Map and MapScreen both contain draw() methods that take an HTML Canvas 2d drawing context as a parameter, and which take care of drawing themselves when requested. The code for both Map and MapScreen is here: &lt;a href="http://www.buyog.com/code/loc/map.js"&gt;map.js&lt;/a&gt;, and the data file is here: &lt;a href="http://www.buyog.com/code/loc/mapData.js"&gt;mapData.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the code for the new map was done, there was still the matter of encoding the map data in a way the Map/MapScreen classes could use. I started out hand-coding the map data myself, but this soon proved to be the gateway to madness, and I decided that I needed to build a map editing tool. This would be useful, I reasoned, not only in terms of saving me time now, but also because it would allowing for custom map creation in the future (assuming I live long enough to get this beast fully running!).&lt;/p&gt;

&lt;p&gt;At any rate, after a few days of spare-time coding, I came up with this &lt;a href="http://www.buyog.com/code/loc/part2/mapper.html"&gt;Mapper&lt;/a&gt; tool. Two caveats, though: 1, the user interface is pretty terrible, since I built this for myself, not for the average user, and 2, performance is pretty sluggish. The large map on the editor page is drawn in the same way as the map in the game itself, only repeated (16x8) 128 times in rapid succession, once for each individual screen. A good CPU helps a lot, and so does having a good browser: Google Chrome runs it about 10 times faster than Firefox 3.0 (which complains with the "unresponsive script" dialog box on my home PC... but will finish soon thereafter if you click "continue"). That said, the latest nightly build of Firefox 3.1, aka &lt;a href="http://www.mozilla.org/projects/firefox/3.1a1/releasenotes/"&gt;Shiretoko&lt;/a&gt;, is quite a bit better... probably owing to its revamped &lt;a href="https://wiki.mozilla.org/JavaScript:TraceMonkey"&gt;&lt;em&gt;TraceMonkey&lt;/em&gt;&lt;/a&gt; JavaScript engine). Code for the mapper tool is here: &lt;a href="http://www.buyog.com/code/loc/mapper.js"&gt;mapper.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway, after a few days of spare-time work and referring often to the original overworld map image, I've finished encoding the map, and the new version of the game is &lt;a href="http://www.buyog.com/code/loc/part2/index.html"&gt;here&lt;/a&gt;. Basically the same functionality as from &lt;a href="http://www.buyog.com/code/loc/part1/index.html"&gt;Part 1&lt;/a&gt;, but with a &lt;em&gt;much&lt;/em&gt; smaller footprint. I've also started to implement collision detection, which the tiled map makes quite a bit simpler, but considering how long it took me to encode the map tile data, that task kind of took over this step of the process.**&lt;/p&gt;

&lt;p&gt;Next time, we're going to finish implementing collision detection, and introduce the missing &lt;img src="http://www.buyog.com/code/loc/web/armos0.png" alt="armos"/&gt; Armos statues (&lt;em&gt;hint: they're not part of the current map for a reason&lt;/em&gt;)!&lt;/p&gt;

&lt;p&gt;* &lt;em&gt;Footnote&lt;/em&gt;: Some of you may have no doubt noticed that there is quite a bit of duplication in the map tiles I chose to use, as many tile designs are represented three different times in three different colors (brown, green, and gray). Some of you may even point out that I could have accomplished this same thing with a smaller tile palette, if I implemented the idea of multiple palettes at the same time (the downloadable Zelda clone &lt;a href="http://www.zeldaclassic"&gt;Zelda Classic&lt;/a&gt; does it this way, for example). Well, yeah, but I didn't want to even &lt;em&gt;think&lt;/em&gt; of the performance hit I would have to take to do image re-coloring in JavaScript/canvas, so intentionally avoided that road. Maybe I'll try it out later on when Canvas has had a chance to mature a bit more in the modern browsers.&lt;/p&gt;

&lt;p&gt;** &lt;em&gt;Footnote 2&lt;/em&gt;: You may notice some blurring and visual artifacts in this new version of the game map; these appear to be due to the fact that I'm scaling the game up to 2x its original size, so I'm going to have to experiment with resizing it differently, or keeping it in its original 256x240 size. As with the Mapper performance, Chrome seems to handle this much better than Firefox, but a new solution is probably in order.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-5810572384946621664?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/5810572384946621664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-day-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5810572384946621664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/5810572384946621664'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2009/01/cloning-zelda-day-2.html' title='Cloning Zelda, part 2: Tile thing'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-7934370493811868535</id><published>2008-12-19T02:34:00.004-05:00</published><updated>2009-09-10T13:14:36.114-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Zelda'/><category scheme='http://www.blogger.com/atom/ns#' term='clone'/><title type='text'>Cloning Zelda in JavaScript: Part 1 of ?</title><content type='html'>&lt;p&gt;Inspired by &lt;a href="http://blog.nihilogic.dk/2008/04/super-mario-in-14kb-javascript.html"&gt;all&lt;/a&gt; &lt;a href="http://www.blobsallad.se/"&gt;of&lt;/a&gt; &lt;a href="http://andrewwooldridge.com/canvas/canvasgame001/canvasgame002.html"&gt;the&lt;/a&gt; &lt;a href="https://developer.mozilla.org/En/MSX_Emulator_(jsMSX)"&gt;HTML 5&lt;/a&gt; &lt;a href="http://www.benjoffe.com/code/demos/canvascape/"&gt;Canvas-powered&lt;/a&gt; &lt;a href="http://blog.nihilogic.dk/2008/12/domtris-yet-another-tetris-clone.html"&gt;JavaScript&lt;/a&gt; &lt;a href="http://blog.nihilogic.dk/2008/07/wolfenflickr-3d-unlikely-mashup.html"&gt;games&lt;/a&gt; that have been popping up, I wanted to see what all the fuss is about. Now I know... it's 2:30 in the morning, I've been working on this for the past 5 hours, and I'm forcing myself to blog my status and go to bed.&lt;/p&gt;

&lt;p&gt;Anyway, I've noticed that, despite all of the dozens and dozens of online Super Mario clones (all of which my 6-year-old has on the main tab of his iGoogle page, but that's a story for another day), there aren't any webby Zelda clones! So I decided it was up to me to take up the challenge... as a programming/learning exercise, I've started writing a pure JavaScript (no Flash/Flex/Java/etc) clone of the original NES game "The Legend of Zelda".&lt;/p&gt;

&lt;p&gt;So far I've got the overworld map in, and the player character (Link) can move from screen to screen (albeit without being constrained by things like mountains and oceans, because I haven't implemented collision detection yet!) Keyboard support is in, but there's also a set of buttons duplicating the NES controller which you can use as well:
&lt;a href="http://www.buyog.com/code/loc/part1/index.html"&gt;The Legend of Canvassa&lt;/a&gt;
(yeah, I know, stupid name... =P)&lt;/p&gt;

&lt;p&gt;Since this uses the &amp;lt;canvas&amp;gt; tag from HTML 5, it currently only runs in Firefox 2+, Webkit and Opera 9; IE users are out of luck. (Yes, I know there are hacks that enable IE to emulate Canvas... but so far I haven't been able to make them work with my code). I've successfully tested it in Firefox 3 and Chrome, so in theory at least it should work in Safari (Chrome and Safari are both Webkit-based, after all). Opera I don't know.&lt;/p&gt;

&lt;p&gt;Anyway, this is only Part 1 of what could potentially be a lengthy project, and I suspect I'll continue to scratch this itch over the coming weeks, so look for more updates as they come.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-7934370493811868535?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/7934370493811868535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2008/12/cloning-zelda-in-javascript-day-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7934370493811868535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/7934370493811868535'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2008/12/cloning-zelda-in-javascript-day-1.html' title='Cloning Zelda in JavaScript: Part 1 of ?'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6970559667014593932.post-9144921587400175166</id><published>2008-09-20T22:44:00.000-05:00</published><updated>2009-06-19T14:25:14.766-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EFR'/><title type='text'>Electronic Film Reviews: Customize your viewing!</title><content type='html'>Long time no blog posts in this corner of my domain. I'll try to do better.

Tonight I finally got around to watching Speed Racer with my car-obsessed 6-year-old son, since it hit RedBox earlier this week. The story dragged in a few places and a couple of the scenes were a bit too intense for him, plus the script was a bit too free with cuss words I'd rather not have him repeating: enter &lt;a href="http://efr.byu.edu/"&gt;the EFR project&lt;/a&gt;!

I've been working on this software for several years (on and off) with good friend, mentor, and professor Alan Melby at BYU Provo. In a nutshell, it gives you the ability to take any off-the-shelf DVD and make your own, totally customized playback experience: you can skip scenes, blank or mute bits you don't want to see and/or hear, flip between different audio tracks and subtitles on the fly, or even play clips out of order if you want! I did all the editing for Speed Racer in the space of about 2-1/2 hours last night after he was in bed, only just slightly stretching the 2-hour runtime of the movie as I edited while pre-screening it with my son's needs in mind. (In retrospect, I should have cut more of the talking-head parts and just left in the mind-blowing race scenes. But I digress...)

Anyway, if any of this sounds intriguing and you wanna "kick the tires" and give the software a test drive, hit the URL up above for the download package. A couple of things to bear in mind, however:
&lt;ul&gt;
&lt;li&gt;the authoring system isn't included in the above link -- if you're interested, &lt;a href="mailto:ryancorradini@yahoo.com"&gt;email me&lt;/a&gt; and I'll send it to you. Eventually there will be a full installer for the authoring suite, but we're not quite there yet.&lt;/li&gt;
&lt;li&gt;it doesn't yet support Windows Vista (or non-Windows operating systems for that matter. Sorry, Mac &amp; Linux folks.)&lt;/li&gt;
&lt;li&gt;You need to already have a working DVD decoder on the machine you're going to use this on -- the EFR applications simply build on top of them.&lt;/li&gt;
&lt;li&gt;This isn't a plug-and-play system like ClearPlay and others of that stripe -- you need to either create an EFR (Electronic Film Review) for a film yourself, or acquire one from someone else and create a playlist from that, customizing it to your tolerances&lt;/li&gt;
&lt;/ul&gt;

That last bullet point bears expansion: this software isn't for people who just want to put in a DVD and have a set-top player decide what to show or not show. It requires a bit more forethought and effort, but ultimately I would choose this approach even if I wasn't personally involved in the effort - it gives you the ultimate control and flexibility, because after all, who knows your viewing preferences better than you yourself? ;)

Enjoy, and please feel free to &lt;a href="mailto:ryancorradini@yahoo.com"&gt;leave me feedback&lt;/a&gt; if you like it, don't like it, can't make it work, etc. Things like this always get better the more they're used, and the more reports / feature requests we get from people.

Happy viewing!

Oh, one final note: &lt;a href="http://www.buyog.com/intconcepts/dl/speedracerEFR.zip"&gt;here&lt;/a&gt; is the EFR and associated playlist (CDL) that I made for Speed Racer, just in case anyone wants to use it as the starting point for their own.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6970559667014593932-9144921587400175166?l=palagpat-coding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://palagpat-coding.blogspot.com/feeds/9144921587400175166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://palagpat-coding.blogspot.com/2008/09/electronic-film-reviews-customize-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/9144921587400175166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6970559667014593932/posts/default/9144921587400175166'/><link rel='alternate' type='text/html' href='http://palagpat-coding.blogspot.com/2008/09/electronic-film-reviews-customize-your.html' title='Electronic Film Reviews: Customize your viewing!'/><author><name>Ryan Corradini</name><uri>https://profiles.google.com/110121263665124745799</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-nAqcOgVRWpU/AAAAAAAAAAI/AAAAAAAAAcY/UQW9BiecXrQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
