<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>ShaunInman.com</title>
<link>http://www.shauninman.com/</link>
<description></description>
<copyright>Copyright 2001-2012 Shaun Inman</copyright>
<generator>Shaun Inman&#8217;s Bookend</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<lastBuildDate>Thu, 24 May 2012 16:20:38 GMT</lastBuildDate>

<item>
	<title>Millinaut Postmortem</title>
	<description><![CDATA[<p>This past weekend <a href="http://www.ludumdare.com">Ludum Dare</a> celebrated its tenth anniversary. Ten years of crazy people going it alone to create a game in 48 hours. Two years ago they expanded the event to allow teams to participate in a separate but concurrent 72 hour jam. This is my fourth Ludum Dare (<a href="/archive/2011/05/02/breathing_room_postmortem">1</a>, <a href="/archive/2011/08/22/data_entry_sentry_postmortem">2</a>, <a href="/archive/2011/12/21/sinkhole_postmortem">3</a>) but my first as a jam participant. I teamed up with <a href="http://mrgan.com/">Neven Mrgan</a> and <a href="http://alexogle.com/">Alex Ogle</a> to create <a href="/ludumdare/millinaut/">Millinaut</a>.</p>

<p><a href="/ludumdare/millinaut/"><img src="/assets/images/millinaut.png" alt="" title="" /></a></p>

<p>Neven was working from Portland and Alex and I from Chattanooga in the <a href="http://tubatomic.com">Tubatomic</a> offices. (Trivia: The Tub offices are above an event space that hosted <em>two</em> proms during this event.) We used <a href="http://db.tt/OYPKyTRx">Dropbox</a> to share files and Skype to bridge the two locations. (Did you know that on the iPad 3 video chat will drain the battery faster than USB can charge it? Neither did I.) We did very little preparation in advance of the theme annoucement. I made sure <a href="http://www.adobe.com/products/flash-builder.html">Flash Builder</a> still worked and figured out how to import <a href="http://www.mapeditor.org">Tiled</a> maps into <a href="http://flixel.org">Flixel</a>. </p>

<p>As Neven <a href="http://mrgan.tumblr.com/post/21695065510/millinaut">said</a>, &#8220;Flash, lol&#8221;. Why Flash instead of HTML5? My last two Ludum Dare games were HTML5 and the results were really lackluster. Zero to poor audio support, terrible mobile performance, and ugh, the choice between anti-aliasing or memory devouring in-canvas scaling. I&#8217;d rather create a good experience on one platform than a poor experience on many.</p>

<p>Like everyone else we got the theme &#8220;Tiny World&#8221; at 9 Eastern/6 Pacific on Friday night. While brainstorming we touched on Liliputians, Innerspace, and Alan Moore&#8217;s Voice of the Fire. We talked about the myriad things that can happen in small spaces, phonebooths, hotels, airplane cabins, and in our own heads. About small physical spaces observed over huge stretches of time. The idea of splitting yourself into smaller and smaller pieces and using the discarded pieces to progress. </p>

<p>An early narrative saw the player in a coma, wandering around inside his own head, piecing together the experiences that lead him to and eventually out of his current predicament. Was he a heroic fireman or a poisoned king? A victim of a drowning or a car accident? An astronaut knocked unconscious during reentry? We talked about additive level design where the entire game would play out in one room with each colected item filling in a narrative blank and adding more detail and new challenges to the game world. A player would control ego, super ego and id. The idea of an introspective totem pole eventually lead to the segmented gameplay mechanic.</p>

<p>While Neven pixelled the protagonist and Alex developed gameplay ideas and continued exploring narrative options I stumbled through <a href="http://pixelpracht.wordpress.com/2010/03/31/flash-tmx-parser/">loading tmx files</a>. Within a couple hours we had the core dropping heads and using them as platforms mechanic working and were able to build and test levels quickly. </p>

<p>Things get blurry here. Collision resolution with a segmented character was really difficult to implement. Adding in enemies and spikes only complicated things. The stack height affects environmental collisions but the damageable hitbox doesn&#8217;t actually change size. Changing the player&#8217;s height caused Flixel&#8217;s camera to shift suddenly or pushed the player into the ground and out the bottom of the level. Once we introduced enemies the idea of activating the heads, one moving up, the other falling was developed. So now the heads had different collision states. For a while you could ride the rocket up the screen (or the planet down) but that ability neutered the challenge of the vertical platforming.</p>

<p>While I continued to debug and add features, Neven and Alex both designed levels to explore the gameplay possibilities. Occasionally Neven would create some new characters or animation sequences. Alex performed the unenviable task of building up a library of sound effects and serving as a second pair of eyes and lobes diagnosing bugs in the game. Early Sunday morning I composed a background theme and slept for the first time since Thursday night (I slept 11 hours total during the event which spanned 72 hours plus the 12 hours before we got the theme).</p>

<p>The final 24 hours were focused on polishing what we already had. Inserting sound effects, composing background music and goal fanfare, fixing bugs, refining enemy and projectile interaction, creating more bugs, setting up autotiling and implementing the parallax starfield. Alex figured out how to get cutscenes created in the Flash IDE <a href="http://flashgamedojo.com/wiki/index.php?title=Cutscene_Template">into Flixel</a> and built those out. Neven trimmed the level fat. We had a bit of a scare at zero hour when the Flash Builder release build wouldn&#8217;t load our external levels so we ended up posting the debug build.</p>

<p>Ludum Dare is always a rewarding experience. You have a deadline and a direction and 48 (or 72) hours to see where they take you. At the end of the weekend you have something that didn&#8217;t exist before. It&#8217;s simultaneously exhausting and rejuvenating. You can <a href="http://tweetlibrary.com/shauninman/millinaut">relive our experience</a> and if you participated you can <a href="http://www.ludumdare.com/compo/ludum-dare-23/?action=preview&amp;uid=11930">rate our game</a>.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F04%2F24%2Fmillinaut_postmortem&amp;seed_title=Millinaut+Postmortem</link>
	<guid isPermaLink="false">1567@http://www.shauninman.com/</guid>
	<category>Collaborations</category><category>Gaming</category>
	<pubDate>Tue, 24 Apr 2012 21:38:00 GMT</pubDate>
</item>
<item>
	<title>Level Design, Aspect Ratios &amp; Camera Behavior</title>
	<description><![CDATA[<p>It&#8217;s no secret that I&#8217;m working on a new iOS game. (Nope, not <a href="/archive/2010/02/23/mimeo_and_the_kleptopus_king">Mimeo</a>, still don&#8217;t feel like I have the chops to pull that off. Yet.) While I haven&#8217;t said too much about it yet, like Mimeo, the new game is a 2d platformer targeting both the iPhone/iPod touch and the iPad. The different aspect ratios of the two device types present some unique challenges when designing levels. (Development is overlapping with a number of other projects/responsibilities so I&#8217;ve been lax in my <a href="/liftoff/">development diary</a> duties for this game. <em>*dusts off blog*</em>)</p>

<p>Levels come in four varieties: a single screen tall and wide (room), a single screen tall and multiple screens wide (corridor), a single screen wide and multiple screens tall (shaft), or multiple screens wide and tall (cavern). Like <a href="/lastrocket/">The Last Rocket</a> the new game has an 8-bit aesthetic so a screen on an iPad is 256x192 pixels and 240x160 on an iPhone (both scaled squarely to exact device resolution). </p>

<p><img src="/assets/images/aspect-screens.png" alt="" title="" /></p>

<p>Obviously, a single iPad screen won&#8217;t fit on an iPhone screen without the camera drifting vertically on corridors, horizontally on shafts, or both in rooms and caverns (vertical drift can be minimized with the use of a <a href="http://www.youtube.com/watch?v=nryuCql2k9A">trap</a>). The Last Rocket sidestepped the issue with single iPhone screen sized levels and a tile set that resolves to black so the unused area of the iPad screen is unnoticeable.</p>

<p>The solution I&#8217;ve decided on requires a slightly modified camera behavior and that some simple rules be observed when designing levels.</p>

<p>The camera still follows the trap (instead of the player character) but on the iPhone the camera is snapped to a special bounds rectangle&#8212;unless the player character moves beyond that rectangle. The bounds rectangle is four rows and two columns smaller than the level and offset by two rows and one column from origin.</p>

<p><img src="/assets/images/aspect-bounds.png" alt="" title="" /></p>

<p>Look familiar? On a single screen room, the relationship between the level and the bounds is the same as the relationship between the iPad and iPhone screens. So what happens when the player character moves beyond the bounds? The camera slides to its natural, unsnapped position using the player character&#8217;s current velocity (or a default value when stationary). </p>

<p><img src="/assets/images/aspect-structure.png" alt="" title="" /></p>

<p>The level design considerations are easier to explain. To ensure that an edge is always visible on screen at the edges of a level, the top and bottom three rows and two columns on the left and right must be solid (with obvious exceptions for the doors that connect levels). I also block out some persistent space for the player&#8217;s thumbs (but not on screen buttons!). More on that in another post.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F04%2F04%2Flevel_design_aspect_ratios_camera_behavior&amp;seed_title=Level+Design%2C+Aspect+Ratios+%26amp%3B+Camera+Behavior</link>
	<guid isPermaLink="false">1565@http://www.shauninman.com/</guid>
	<category>Design</category><category>Gaming</category>
	<pubDate>Wed, 04 Apr 2012 19:27:00 GMT</pubDate>
</item>
<item>
	<title>Polished MML Bundle</title>
	<description><![CDATA[<p>A couple of weeks ago <a href="http://8bitmatt.com/">Matt Grimm</a> emailed an update to my <a href="/archive/2010/02/13/an_mml_bundle_for_textmate">TextMate MML bundle</a>. The two big adds are multi-line comments and much improved error reporting. The full list of changes follows:</p>

<ul>
<li>Multi-line comments (syntax highlighting and keyboard shortcuts)  <code>cmd + opt + /</code></li>
<li>Quickly change language to mml (shows in the list of other languages that use this shortcut too)  <code>ctrl + shift + opt + m</code></li>
<li>Easier to read ruby in bundle scripts (string interpolation)</li>
<li>Better cleanup. In some cases .h files were still hanging around.</li>
<li>When compiling fails you&#8217;ll know! Shows in a textmate tooltip. (no more guessing if something worked)</li>
</ul>

<p>Thanks Matt!</p>

<p><a href="/assets/downloads/MML.zip">Download</a> the updated bundle.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F03%2F21%2Fpolished_mml_bundle&amp;seed_title=Polished+MML+Bundle</link>
	<guid isPermaLink="false">1563@http://www.shauninman.com/</guid>
	<category>Collaborations</category><category>Music</category><category>NSF</category>
	<pubDate>Wed, 21 Mar 2012 18:07:00 GMT</pubDate>
</item>
<item>
	<title>Sprint by South West</title>
	<description><![CDATA[<h2 id="h2-or-almost-the-most-expensive-bus-ride">Or (Almost) The Most Expensive $1 Bus Ride</h2>

<p><img src="/assets/images/run.gif" alt="" title="" /></p>

<p><a href="http://www.jenseninman.com/blog/text/13461106/sxswi">Leslie</a> and I arrived in Austin yesterday for our <a href="http://www.shauninman.com/archive/2005/03/24/a_proposal_at_thirty_four_thousand_feet">seventh SXSW</a>. We use to take a taxi from the airport until we discovered the <a href="http://www.capmetro.org/riding/airport.asp">$1 Capital Metro bus</a> a few years go. This year I did something unbelievably stupid: I forgot my laptop bag on the bus.</p>

<p>We got off at 4th and Congress and walked about a block before I realized what I had done. I immediately broke into a sprint in the direction I thought the bus was headed (it was already out of sight). Hands on my head, muttering, &#8220;Oh fuck, oh fuck, oh fuck&#8221;, I clopped along in my flip-flops for about a block before whipping them off for more speed. I dashed down every cross street, trying to desperately to pull up my mental map of downtown Austin (you don&#8217;t so much navigate Austin at SXSW as you do flock).</p>

<p>As I reached the borders of that map I almost ran past the bus at a stop light. I manically banged on the bus door, hoping the driver would recognize me from exiting minutes earlier and not mistake me for some deranged, barefoot maniac (though he wouldn&#8217;t have been too far off). Fortunately my laptop bag was still aboard, having slid out of sight, under the seat I had occupied.</p>

<p>I am fortunate I was able to intercept the bus before it continued on its way. In the laptop bag was my laptop, my iPad, my DS Lite and a handful of games, our house keys, our sole car key and clicker, and my antibiotics for the obligatory South By Sinus Infection.</p>

<p>There are so many different ways this story could have ended. If we had taken a taxi I might have never seen the bag again. My barefoot sprint could have ended in stitches (there seems to be broken glass everywhere here), or worse, hit by a car or the very bus I was frantically searching for. If Leslie wasn&#8217;t with me I would have had to choose between abandoning my luggage or my livelihood (so long luggage!). I feel bad for all the quantum Shaun&#8217;s that made it this far only to suffer one of these other, less fortunate fates. Sorry guys.</p>

<p><a href="http://tweetlibrary.com/shauninman/sprintby">tl;dr</a></p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F03%2F09%2Fsprint_by_south_west&amp;seed_title=Sprint+by+South+West</link>
	<guid isPermaLink="false">1562@http://www.shauninman.com/</guid>
	<category>Personal</category>
	<pubDate>Fri, 09 Mar 2012 13:44:00 GMT</pubDate>
</item>
<item>
	<title>Detox</title>
	<description><![CDATA[<p>This is an intervention. <a href="/assets/downloads/Detox.safariextz">Detox</a> is a tiny Safari extension that automatically expands shortened t.co links on the Twitter site (third-party desktop app users <del>are out of luck, sorry</del> should see the 1.1 update below). </p>

<p>Ever wonder why links you find via Twitter don&#8217;t show up in your browser history and aren&#8217;t suggested by autocomplete in the url bar? The t.co link shortener serves known browser user agents an HTML page containing a JavaScript or meta refresh redirect (instead of the standard <code>Location</code> header) so that Twitter can stake itself out as the referrer when coming from third-party clients. This confuses Safari.</p>

<p><a href="http://haveamint.com/">Stats are cool and all</a> but only when they don&#8217;t break the experience for your users. </p>

<p><a href="/assets/downloads/Detox.safariextz">Download Detox</a>.</p>

<p>(<a href="http://zackarycorbett.com/">Zackary Corbett</a> made a <a href="http://zyber17.com/detox/">Chrome version</a> too, which may or may not be necessary. Firefox and Opera also appear to be unaffected.)</p>

<h2 id="h2-detox-">Detox 1.1</h2>

<p>Now when you hit a t.co redirect page (from a native client or a direct message from Mail.app) the destination url is added to the document title making the destination url appear in your history and url autocomplete suggestions.</p>

<h2 id="h2-detox-">Detox 1.2</h2>

<p>Added <a href="https://gist.github.com/1792384">code</a> submitted by <a href="https://twitter.com/Orangenhain/status/168065964406079489">Orangenhain</a> that fixes a similar history-breaking problem on Google&#8217;s search results.</p>

<h2 id="h2-detox-">Detox 1.2.1</h2>

<p>Recently Twitter updated their link expansion <code>data</code> attributes. Previously the expanded url could be found in each link&#8217;s <code>data-expanded-url</code> attribute. A recent update duplicates the t.co url in <code>data-expanded-url</code> and puts the true url in <code>data-ultimate-url</code>.</p>

<h2 id="h2-detox-">Detox 1.2.2</h2>

<p>Digging deeper it appears that <code>data-ultimate-url</code> contains the terminal for twice (or more) shortened urls (eg. a t.co&#8217;d bit.ly pointing to the terminal google.com). Detox 1.2.2 Uses <code>data-ultimate-url</code> if available, falling back on the original <code>data-expanded-url</code>. <code>data-expanded-url</code> containing the t.co instead of the expanded url may have just been a temporary Twitter bug. I regret jumping to conclusions but with twice shortened urls the user never sees the intermediate url which is what ultimately lead to the confusion.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F01%2F19%2Fdetox&amp;seed_title=Detox</link>
	<guid isPermaLink="false">1560@http://www.shauninman.com/</guid>
	<category>Apple</category><category>JavaScript</category>
	<pubDate>Thu, 19 Jan 2012 21:35:00 GMT</pubDate>
</item>
<item>
	<title>Stock</title>
	<description><![CDATA[<p>These things I produced in 2011:</p>

<ul>
<li><a href="/lastrocket/">The Last Rocket</a> Though not released until mid-August I started work on what I consider to be my first proper game in early January. The development of this game, more than anything else, shaped the past year. It was critically well received, responsible for a quarter of the year&#8217;s income, and even made <a href="https://twitter.com/matthewdkenyon/status/149484341154680833">Edge</a>, <a href="http://toucharcade.com/2011/12/23/best-ios-games-2011-buyers-guide/">Touch Arcade</a> and <a href="http://www.iphonealley.com/news/iphone-alleys-10-6-best-reviewed-games-of-2011">iPhone Alley</a>&#8217;s year end lists.</li>
<li><a href="/archive/2011/04/18/unplayed">Unplayed</a> I&#8217;d been privately maintaining a list of games I&#8217;ve played or want to play since getting a DS Lite in June of 2006. After briefly dabbling with a Tumblr to maintain the list I wrote this trifle of a web app.</li>
<li><a href="/archive/2011/05/02/breathing_room_postmortem">Breathing Room</a> My first Ludum Dare. Also, an early study from my thinking about level design.</li>
<li><a href="/archive/2011/07/25/cssfrag">CSSFrag</a> A Safari extension for targeting specific DOM elements by url. Passed the torch to <a href="http://karanlyons.com/pinpoint/">Pinpoint</a>.</li>
<li><a href="/archive/2011/06/02/reply_reach">Reply Reach</a>  &amp; <a href="/archive/2011/08/26/past_ats">Past @s</a> Two little JavaScript bookmarklets for use on Twitter.com.</li>
<li><a href="/archive/2011/08/22/data_entry_sentry_postmortem">Data Entry Sentry</a> My second Ludum Dare and my first attempts at a JavaScript/Canvas game. The genesis of the <a href="http://www.ludumdare.com/compo/2011/12/16/si2d-js/">JavaScript port</a> of the Objective-C framework I use for all of my iOS games, SI2d.</li>
<li><a href="/archive/2011/10/20/day_o_mac_menu_bar_clock">Day-O</a> A simple menubar calendar replacement for OS X.</li>
<li><a href="/archive/2011/12/05/chunks">Chunks</a> A native iOS port of my second Ludum Dare game, Data Entry Sentry. I didn&#8217;t promote this as much as I probably should have but a more vocal release might have set expectations too high for this modest little falling block game.</li>
<li><a href="/archive/2011/12/21/sinkhole_postmortem">Sinkhole</a> My third Ludum Dare. A tense little exploration game that I&#8217;m still actively developing. SI2d.js was updated significantly for this game. I even ported it from Canvas to DOM sprites to compare performance (pretty much head to head by the numbers but the Canvas version feels smoother in play and is easier to extend).</li>
<li><a href="/archive/2011/12/26/the_last_rocket_suite">The Last Rocket Suite</a> The <a href="/lastrocket/soundtrack.html">soundtrack</a> from The Last Rocket did pretty well too so I released this string quartet version of three themes from the game.</li>
</ul>

<p>In addition to these wholly new things, I also released a bunch of updates to <a href="http://haveamint.com/">Mint</a> and its <a href="http://haveamint.com/peppermill/">Pepper</a>, <a href="http://feedafever.com/">Fever</a>, <a href="http://shortwaveapp.com/">Shortwave</a>, <a href="/archive/lessn">Lessn</a> and <a href="/noisees/">NoiseES</a>. I&#8217;m also about a month or two into another all new 8-bit iOS game, inspired as much by Metroid and Super Mario Bros 2/Doki Doki Panic as it is by Studio Ghibli&#8217;s films. </p>

<p>All in all, a very productive year.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2012%2F01%2F01%2Fstock_2011&amp;seed_title=Stock</link>
	<guid isPermaLink="false">1559@http://www.shauninman.com/</guid>
	<category>Apple</category><category>CSS</category><category>Design</category><category>Flash</category><category>JavaScript</category><category>Music</category><category>Personal</category><category>Mint</category><category>Gaming</category><category>Fever</category>
	<pubDate>Sun, 01 Jan 2012 19:39:00 GMT</pubDate>
</item>
<item>
	<title>Sinkhole Postmortem</title>
	<description><![CDATA[<p><img src="/assets/images/sinkhole-title.png" alt="" title="" /></p>

<p>This past weekend I participated in my third <a href="http://www.ludumdare.com/">Ludum Dare</a>. I created an HTML5 game called <a href="/ludumdare/alone/sinkhole/">Sinkhole</a> from scratch in 48 hours. It was an awesome experience and the game didn&#8217;t turn out half bad either. <a href="/archive/2011/08/22/data_entry_sentry_postmortem">Last time</a> I had just launched <a href="/lastrocket/">The Last Rocket</a>. This time I had just launched <a href="/chunks/">Chunks</a>, a native port of my previous Ludum Dare creation.</p>

<p>The theme this time around was <a href="http://www.ludumdare.com/compo/ludum-dare-22/">Alone</a>. Unlike the previous two Dares where I came up with three ideas and then slept on them before starting, this time I had an idea I was really excited about and after only half an hour set to work.</p>

<p>The first three lines of <a href="/ludumdare/alone/alone.txt">my notes</a> from that first night read:</p>

<ul>
<li>top-down</li>
<li>exploration by flashlight</li>
<li>something moving in the darkness</li>
</ul>

<p>I wanted there to be an urgency to the exploration. I wanted the antagonists, the stalkers, to be unseen. Let the players&#8217; imagination do the heavy lifting.</p>

<p>I also knew I didn&#8217;t want to have to worry about level design so after bootstrapping the <a href="http://www.ludumdare.com/compo/2011/12/16/si2d-js/">JavaScript framework</a> I cobbled together for the last Ludum Dare I started researching <a href="http://roguebasin.roguelikedevelopment.org/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels">cellular automata</a> and <a href="http://devpro.it/javascript_id_137.html">pathfinding</a> so I could dynamically generate solvable maps to use. I managed to get the skeleton of a solution working (ported from C to JavaScript) before bed the first night.</p>

<p>While falling asleep I started imagining the stalkers&#8217; behavior. After a short delay a stalker appears and attempts to sneak up behind the player. Facing the stalker causes them to freeze. Shining a light on them causes them to flee. But every time one flees another, slightly faster, stalker spawns. The player solves their current problem at the cost of future safety. More impetus to find the exit quickly. </p>

<p>In addition to the unseen threat of the stalkers, the player&#8217;s defensive and discovery tool, light, is limited. The flashlight&#8217;s batteries drain in one minute. Matches burn out after 3 seconds. It takes time to load a new battery or strike a match. During that time visibility is nil. Or rather, you can see the stalkers approach but not the player or the walls of the level. Once the player runs out of light sources and their eyes adjust only slivers of walls are visible on the periphery of their limited cone of vision. The player must rely on these subtle hints and the minimap to find another battery or matchbook to buy them some more time to find the exit.</p>

<p>I eventually fell asleep.</p>

<p>I woke up to the realization that I had attempted (and abandoned) a very similar mechanic during my <a href="/archive/2011/05/02/breathing_room_postmortem">first Ludum Dare</a> (the original Chibi Pan &amp; Pup idea).</p>

<p>Shaking off the thought of repeat failure I quickly implemented a TileMap class in SI2d.js and a way to crop the viewport allowing the &#8220;camera&#8221; to follow the player as they moved across the map. I revisted the touch-based controls then created some rough graphic masks to start implementing the different sized beams of light that define the gameplay. Minimaps came quickly. Around this time I realized that the framerate wasn&#8217;t going to be acceptable on the iPad and implemented keyboard controls as well.</p>

<p>Power-ups, a compass to reveal the exit on the minimap, batteries and matchbooks to recharge your light supply slotted in pretty easily. Stalkers gave me a bit of trouble initially. They needed to spawn outside of the players cone of vision or else they would flee immediately.</p>

<p>The story arrived in the form of four tweets that became the prologue:</p>

<blockquote>
  <p>Tomo the Cartographer was on a routine survey mission in Central America when the earth opened up and swallowed him whole.</p>
  
  <p>Miraculously, he survived falling hundreds of feet and walked away with only a broken arm.</p>
  
  <p>Guide Tomo out of the sinkhole before he runs out of flashlight batteries or burns through all his matches.</p>
  
  <p>It will be a lonely climb back to the surface. At least, Tomo thinks he&#8217;s alone. He <em>hopes</em> he&#8217;s alone.</p>
</blockquote>

<p>Around midnight the second and final night I started on the artwork. Like all of my games to date I limited my palette to only colors the NES was <a href="http://en.wikipedia.org/wiki/File:NES_palette.png">capable of producing</a>. Tomo came together quickly, based largely on the Link sprite from the original Zelda (with a strong Mega Man influence). I used Mario from SMB3 as a referene when drawing his vine climbing animation. I had to redraw the power-ups and background tiles a few times but I eventually arrived at something I was happy with. I had a lot of fun creating the onomatopoeia bursts that represent the stalkers.</p>

<p>The remainder of the last day is a disjointed blur. Lots of revisions to stalker behavior. Persisting inventory between levels. In a remarkable moment of clarity I coded, from memory, in one go, an error-free JavaScript port of my Objective-C TextMap class. This allowed me to get some of Tomo&#8217;s internal dialog on-screen while playing.</p>

<p>The title screen graphic was a happy accident. While trying to draw grass hanging over the edge at the top of the sinkhole I accidentally turned off (or on) another layer producing the masked out, moss-clinging-to-the-sides effect you see in the finished artwork.</p>

<p>By the end of it all I couldn&#8217;t see straight, my own eyes were anti-aliasing the pixel art I had slaved over. But it was totally worth it. It&#8217;s creatively rejuvenating, knowing that you just created something, non-negligible, largely from scratch, in just 48 hours. If you participated in Ludum Dare, please play and rate <a href="http://www.ludumdare.com/compo/ludum-dare-22/?action=preview&amp;uid=4017">my entry</a> (I&#8217;d love any feedback you have as well)!</p>

<p>I&#8217;ve been continuing to develop the game in the days since submitting. Improving collision detection, softening cornering, improving keyboard responsiveness, adding <a href="https://wiki.mozilla.org/GamepadAPI">Gamepad API</a> support, refining power-up frequency and distribution, tuning stalker behavior. Maps no longer regenerate every time you die. The minimap remembers previously explored areas. Inventory reverts to its unique pre-level state rather than resetting completely. <a href="/ludumdare/alone/sinkhole/">Play the updated version of Sinkhole</a>. Who knows, maybe someday there will be an expanded native iOS version.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F12%2F21%2Fsinkhole_postmortem&amp;seed_title=Sinkhole+Postmortem</link>
	<guid isPermaLink="false">1556@http://www.shauninman.com/</guid>
	<category>JavaScript</category><category>Gaming</category>
	<pubDate>Thu, 22 Dec 2011 03:46:00 GMT</pubDate>
</item>
<item>
	<title>Chunks</title>
	<description><![CDATA[<p><strong>Update</strong> Chunks is <a href="/chunks/">out now</a>! Grab the <a href="/chunks/chunks-osv.zip">four track OSV</a> while you&#8217;re at it.</p>

<p>Later tonight or early tomorrow I&#8217;ll have a new game in the App Store. (For real this time. Last week <a href="/horrorvacui2/">Horror Vacui 2</a> showed up on a number of App Store new release lists for no apparent reason despite being released over a year ago.) It&#8217;s a small game with more in common with Horror Vacui than <a href="/lastrocket/">The Last Rocket</a>. And it might look familiar.</p>

<p><a href="/chunks/"><img src="/assets/images/chunks.png" alt="Introducing the Chunks in Data Entry Sentry" title="" /></a></p>

<p><a href="/chunks/">Chunks</a> is a native iOS port of my most recent <a href="http://www.ludumdare.com/compo/about-ludum-dare/">Ludum Dare</a> game <em>Escape! Data Entry Sentry</em>. The core gameplay mechanic and most of the graphics were created over a <a href="/archive/2011/08/22/data_entry_sentry_postmortem">48 hour period</a> shortly after releasing The Last Rocket. While I&#8217;ve been working on a new, more ambitious 8-bit platformer for iOS (somewhere between The Last Rocket and the unreleased <a href="/archive/2010/02/23/mimeo_and_the_kleptopus_king">Mimeo and the Kleptopus King</a> in scale) I&#8217;ve also made time to rename and refine Chunks for a proper release.</p>

<p>In addition to some gameplay tweaks and instructional UI, I composed three new chiptunes, a short game over jingle plus a handful of sound effects. The themes were inspired by falling block giants Tetris and Dr. Mario (with a little The Guardian Legend thrown in for good measure). The tempo of the background music increases with the speed of the conveyor as you play. This change is imperceptible from level to level but after a while you really start to feel the frantic increase in momentum. Grab the <a href="/assets/music/nsfe/chunks.nsfe">NSFe</a> and give it a listen in <a href="/noisees/">NoiseES</a>.</p>

<p>Chunks is a universal app so you can play on your iPhone, iPod touch or iPad and includes Game Center leader boards for high score and highest level. It&#8217;s a small game with humble origins so it&#8217;s only a buck. <a href="/chunks/">Check it out tomorrow!</a></p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F12%2F05%2Fchunks&amp;seed_title=Chunks</link>
	<guid isPermaLink="false">1554@http://www.shauninman.com/</guid>
	<category>Apple</category><category>Music</category><category>Gaming</category><category>NSF</category>
	<pubDate>Mon, 05 Dec 2011 16:47:00 GMT</pubDate>
</item>
<item>
	<title>Day-O</title>
	<description><![CDATA[<p><img src="/assets/images/day-o.png" alt="Day-O" title="" /></p>

<p><a href="http://shauninman.com/assets/downloads/Day-O.zip">Day-O</a> is a simple menu bar clock replacement with a simple calendar for your Mac. It&#8217;s free, as-is (which means I&#8217;m not providing support, taking feature requests, addressing perceived inadequacies or releasing the source code). Here&#8217;s how it came to be:</p>

<p>My late upgrade to Lion was relatively painless. The only casualty was <a href="http://www.objectpark.net/mcc.html">MenuCalendarClock</a>. It somehow clobbers the Dictionary shortcut key command <em>and gesture</em> which I use daily (if not hourly). I thought I could live without MMC. I don&#8217;t use any calendar apps so I was just using the free version for the simple date icon and convenient fly-out calendar. I thought the system menu clock would suffice. Really, how frequently did I use the fly-out calendar?</p>

<p>Turns out, quite a bit. I tried a few replacements but couldn&#8217;t stand any of their date icons. MMC developer Objectpark seems to have gone quiet. Fortunately, as I <a href="https://twitter.com/shauninman/status/126767392633270272">quipped on Twitter</a>, I&#8217;ve &#8220;never met a wheel I didn&#8217;t want to reinvent.&#8221;</p>

<p>I was able to piece something together from <a href="http://undefinedvalue.com/2009/07/07/adding-custom-view-nsstatusitem">various</a> <a href="http://files.semaja2.net/NSStatusItem%20-%20ObjC.html">NSStatusItem</a> <a href="http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/">tutorials</a>, the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDatePicker_Class/Reference/Reference.html">NSDatePicker Class Reference</a>, <a href="http://stackoverflow.com/questions/5143117/how-can-i-reload-the-com-apple-systemuiserver-preferences-into-the-systemuiserve">Stack Overflow</a> <a href="http://stackoverflow.com/questions/1857603/lsuielement-behaves-inconsistently-with-activateignoringotherapps/7823173#7823173">answers</a> and <a href="https://github.com/carpeaqua/Shared-File-List-Example">GitHub repositories</a>. </p>

<p>I may or may not have had this <a href="http://www.youtube.com/watch?v=Euc9MMRtuSg">YouTube video</a> on repeat in the background the entire time.</p>

<p><a href="http://shauninman.com/assets/downloads/Day-O.zip">Download Day-O</a>.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F10%2F20%2Fday_o_mac_menu_bar_clock&amp;seed_title=Day-O</link>
	<guid isPermaLink="false">1552@http://www.shauninman.com/</guid>
	<category>About</category>
	<pubDate>Thu, 20 Oct 2011 19:42:00 GMT</pubDate>
</item>
<item>
	<title>Past Ats</title>
	<description><![CDATA[<p>Have you ever had deja who? You know, when the name or avatar of someone who just mentioned you on Twitter looks familiar and unfamiliar at the same time? Have they tweeted you before?</p>

<p>Drag this <a href="javascript:(function(){var%20f=$.trim($('div.focused-stream-item%20a.tweet-screen-name').text());var%20t=$.trim($('#screen-name').text());$('#search-query').val('from:'+f+'%20to:'+t)[0].form.submit();})();" onclick="alert('Drag me to your bookmarks bar!'); return false;">Past @s</a> link to your bookmarks bar. Then the next time this happens select the tweet and click the bookmarklet to perform a quick Twitter search for recent tweets from this person to you.</p>

<p>Think that&#8217;s useful? You might also like my <a href="/archive/2011/06/02/reply_reach">Reply Reach</a> bookmarklet.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F08%2F26%2Fpast_ats&amp;seed_title=Past+Ats</link>
	<guid isPermaLink="false">1549@http://www.shauninman.com/</guid>
	<category>JavaScript</category><category>Web</category>
	<pubDate>Fri, 26 Aug 2011 13:09:00 GMT</pubDate>
</item>
<item>
	<title>Take a Chance</title>
	<description><![CDATA[<p>Recently (and four years ago when I first wrote the draft for this post in November 2007), I needed a function that had an <code>x</code> in <code>y</code> chance of returning true. Some quick googling turned up nothing (I don&#8217;t even know what you would call this). After some trial and error I came up with this:</p>

<pre><code>function chance(x, y)
{
    // return Math.ceil(Math.random() * y) &lt;= x;
    return Math.random() &lt;= x/y;
};
</code></pre>

<p>Which in my testing behaves as intended. <code>chance(1, 32);</code> has an approximately 3% chance of returning <code>true</code>. <code>chance(99, 100);</code> has an approximately 99% chance of returning <code>true</code>.</p>

<p>Hopefully this will save someone else some unnecessary head-scratching.</p>

<p><strong>Update</strong> K.M. <a href="https://twitter.com/twirp/status/106432792509952001">points out</a> that <code>Math.random()</code> returns a number between 0 (inclusive) and 1 (exclusive) so the <code>Math.ceil()</code> is <a href="https://twitter.com!/twirp/status/106420254577655808">unnecessary</a>.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F08%2F24%2F1_in_x_chance_javascript_function&amp;seed_title=Take+a+Chance</link>
	<guid isPermaLink="false">1158@http://www.shauninman.com/</guid>
	<category>JavaScript</category>
	<pubDate>Wed, 24 Aug 2011 16:31:00 GMT</pubDate>
</item>
<item>
	<title>A Treatise on Touch</title>
	<description><![CDATA[<p>With the recent release of <a href="/lastrocket/">The Last Rocket</a> and this past weekend&#8217;s <a href="/archive/2011/08/22/data_entry_sentry_postmortem">Ludum Dare</a> I&#8217;ve been thinking a lot about touch screen controls in platformers. </p>

<p>I&#8217;m increasingly of the opinion that onscreen buttons are not the way forward. Overlays are a poor substitute for a physical d-pad or buttons; it&#8217;s too easy for fingers to drift while attention is focused elsewhere onscreen or to obstruct immediate threats to the player resulting in unfair deaths.</p>

<p>They create the expectation of familiar behaviors that they can&#8217;t deliver. When you use a gamepad your fingers don&#8217;t hover over the buttons waiting to touch each individually. Your thumbs rest on the buttons, then depress and/or pivot to adjacent buttons as needed. On a touch screen it is impossible to distinguish between a resting touch and a touch with intention. (Hold and slide might effectively simulate an analog stick but I&#8217;m primarily interested in 2D games where an analog stick offers little benefit.)</p>

<h2 id="h2-deferred-gratification">Deferred Gratification</h2>

<p>If an action is triggered immediately at the beginning of a touch (the press) that&#8217;s the only action that touch can trigger leaving you to rely on separate onscreen buttons to provide multiple distinct actions. But, if you delay triggering the primary action to the release, a single touch can be overloaded with at least three distinct actions.</p>

<p>In The Last Rocket, the press triggers a crouching state. From there the player can release to launch (like releasing a spring) or swipe to step in the direction of the swipe. Three distinct actions, zero buttons. While airborne, the press prepares to land in a crouching state, release reverses direction, and when snared by a fan or vent, a swipe chooses a direction. Again, three distinct actions, no buttons. </p>

<p>If Flip launched or reversed on the press then additional onscreen buttons would be required to support the additional actions. This new approach may at first seem contrary to past experience with gamepads and their physical buttons but is intuitive and easily grasped in the new context of a touch screen.</p>

<h2 id="h2-potential-application">Potential Application</h2>

<p>I can imagine a fairly traditional platformer that uses this buttonless approach (there may already be one, I&#8217;m not the most voracious iOS gamer): The screen is split down the middle into two equal, invisible regions representing left and right. A press starts the character running in one direction or the other, depeding on which side of the screen is touched (which the player intuitively understands as run towards the touch). A release triggers a jump that maintains the previous forward momentum. A quick tap from a standstill would be a straight jump up. A release after a period of running would be a leap forward. Maybe another touch on the same side cancels vertical momentum, limiting the height of the jump (which the player intuitively understands as the duration their finger is off the screen). A tap in the opposite direction could cease forward momentum without triggering a forward jump.</p>

<p>Definitely something I plan to explore further after submitting The Last Rocket 1.1 to the App Store and porting Data Entry Sentry to iOS.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F08%2F23%2Fa_treatise_on_touch&amp;seed_title=A+Treatise+on+Touch</link>
	<guid isPermaLink="false">1548@http://www.shauninman.com/</guid>
	<category>Apple</category><category>Gaming</category>
	<pubDate>Wed, 24 Aug 2011 00:35:00 GMT</pubDate>
</item>
<item>
	<title>Data Entry Sentry Postmortem</title>
	<description><![CDATA[<p>Having just released <a href="/lastrocket/">The Last Rocket</a> I wasn&#8217;t sure I had the energy to participate in this weekend&#8217;s <a href="http://www.ludumdare.com/compo/">Ludum Dare</a>. But <a href="/archive/2011/05/02/breathing_room_postmortem">looking back</a> on the last one I remembered what an enjoyable (grueling) and reinvigorating (exhausting) experience it was. So about an hour an a half before they announced the theme I decided to do it. You can play the result, <a href="http://www.ludumdare.com/compo/ludum-dare-21/?action=preview&amp;uid=4017">Data Entry Sentry</a> (looks best in browsers that support the CSS3 image-rendering property, like the <a href="http://nightly.webkit.org/">Webkit Nightly</a>, but plays best on the iPad), or continue reading for the postmortem.</p>

<p>This time the theme was <a href="http://www.ludumdare.com/compo/ludum-dare-21/">Escape!</a>. Like last time I came up with three ideas and slept on them before starting any work:</p>

<ul>
<li>Farmbreak!: You place obstacles to prevent animals from escaping their pens. Different animals have different abilities (ram, jump, burrow, fly) and each requires a different type of barrier to contain. Yawn.</li>
<li>Escape from Zombie Hall: Sort of a Space Invaders/Smash TV mashup. A first-year dorm resident of Zombinski Hall is trapped in a zombie outbreak. In the first part of each stage the player moves left and right blasting back the oncoming zombie horde with a shotgun (Space Invaders). One zombie is holding the key to the exit which is behind the player. When that zombie is blasted the key pops out and the player must rush in with a 360 chainsaw attack (Smash TV), collect the key and make it back to the exit in one piece. The only thing less inventive than a clone plus zombies is a clone plus ninjas.</li>
<li>Data Entry Sentry: Can you make a game about escaping data? Can you make it fun? You can certainly try. Chunks of data slide down multiple conveyors towards a parser and buffer. Some of the data chunks are gremlins. If a gremlin hits the parser it eats all the data between it and its pair. The goal is to fill the buffer without overflowing.</li>
</ul>

<p>Waking up Saturday morning, Data Entry Sentry seemed the most interesting, unique option. So where do I start? For my first Ludum Dare entry, <a href="/breathingroom/levels/">Breathing Room</a>, I used <a href="http://flixel.org/">Flixel</a>. I&#8217;m really not a fan of keyboard and mouse games and really enjoyed the simplicity of tapping in The Last Rocket. I wanted to make a game that I could play on the iPad. So Flash was out.</p>

<p>After doing some <a href="https://gist.github.com/768272">quick research</a> on HMTL5 game engines I decide to roll my own. Using John Resig&#8217;s <a href="http://ejohn.org/blog/simple-javascript-inheritance/">Simple JavaScript Inheritance</a> I put together a streamlined JavaScript approximation of the iOS framework I used for <a href="/hv2/">Horror Vacui 2</a> and The Last Rocket. </p>

<p>The framework is pretty simple (view source on <a href="/ludumdare/escape/">the game</a>). The primary class is Surface which can have a parent and children Surfaces, has a rectangle for size and position and knows how to render and update itself. Surface is meant to be extended but is also useful for grouping elements at a given zIndex. The GameSystem class extends Surface and is responsible for creating the canvas element and is used as the System singleton so that the Texture and Rectangle classes can draw to the screen. An InputManager class is used by other objects to register to receive input events. Everything else extends Surface. State automatically takes the dimensions defined when initializing GameSystem. Rectangle draws colored rectangles. Tile draws individual tiles in a tilesheet. Wallpaper repeats a single image. SurfaceY is just a Surface that sorts (and renders) its children by y coordinate instead of zIndex.</p>

<p>By the end of the first day I had an ugly, <a href="/ludumdare/escape/prototype.html">playable prototype</a>.
By noon on Sunday I had a design and simple animations I was happy with:</p>

<p><img src="/assets/images/data-entry-sentry.png" alt="" title="" /></p>

<p>One of the trickier elements of the design was the level numbers. Because of the perspective, the tens and ones columns require two different sets of numbers. I created a special LevelNumber class to properly render the text from a tilesheet containing numbers drawn in both perspectives.</p>

<p>The remainder of Sunday was spent rewriting PlayState to use the new Chunk class and integrate the graphics and complicated zIndexing and stacking behavior. The bulk of the game logic lives in the PlayState update method. Chunks, a subclass of Surface, are moved between different Surfaces (conveyor, stack, Chomplies and dying) and behave differently depending on which Surface they inhabit. Initially this was done as an easy way to manage Chunk zIndexes but ended up being really useful for implementing the behaviors unique to each section of the game board.</p>

<p>As an aside, in The Last Rocket, instead of subclassing subclasses of Surfaces and adding behavior I have an Entity class (which has a little less overhead than a Surface) that has one or more Surfaces. States then iterate over entities which are responsible for the behavior of their Surfaces.</p>

<p>If I had more time I would have liked to create some 8-bit tunes and sound effects to complement the graphics but HTML5 audio still seems to be a tricky proposition on iOS. </p>

<p>Ultimately, Ludum Dare was, again, a rewarding experience. Maybe once <a href="http://dribbble.com/shots/240136-8-bit-Game-Center">The Last Rocket</a> and <a href="http://dribbble.com/shots/233680-Noisiest-Entertainment-System">NoiseES</a> updates are done I&#8217;ll port <a href="/ludumdare/escape/">Data Entry Sentry</a> back to iOS and finish it up properly.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F08%2F22%2Fdata_entry_sentry_postmortem&amp;seed_title=Data+Entry+Sentry+Postmortem</link>
	<guid isPermaLink="false">1547@http://www.shauninman.com/</guid>
	<category>Apple</category><category>Design</category><category>JavaScript</category><category>Gaming</category>
	<pubDate>Mon, 22 Aug 2011 14:29:00 GMT</pubDate>
</item>
<item>
	<title>Lift Off!</title>
	<description><![CDATA[<p><a href="http://itunes.apple.com/us/app/the-last-rocket/id429747672?ls=1&amp;mt=8" style="display: block; margin-left:-10px;"><img src="/assets/images/lift-off.png" width="500" height="500" alt="We have lift off!"></a></p>

<p>The Last Rocket has been approved and is <a href="http://itunes.apple.com/us/app/the-last-rocket/id429747672?ls=1&amp;mt=8">available now on the App Store</a>! Check out <a href="http://thelastrocket.com/">the site</a> for the trailer, some iOS wallpapers and, if you still have Flash Player installed, a preview of the music.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F08%2F11%2Flift_off&amp;seed_title=Lift+Off%21</link>
	<guid isPermaLink="false">1545@http://www.shauninman.com/</guid>
	<category>Apple</category><category>Gaming</category>
	<pubDate>Thu, 11 Aug 2011 12:31:00 GMT</pubDate>
</item>
<item>
	<title>CSSFrag Safari Extension</title>
	<description><![CDATA[<p><strong>Update</strong> <a href="http://karanlyons.com/">Karan Lyons</a> has created a <a href="http://karanlyons.github.com/CSSFrag/">new and significantly improved version</a> of CSSFrag that (among other improvements) can automatically generate CSSFrag links from the context menu. I have now passed the torch of CSSFrag Safari Extension maintainer to Karan. We tried to rig up a way to smoothly and automatically update users of my extension to his but Safari didn&#8217;t like the hand-off so you&#8217;ll need to manually update to the new version.</p>

<p>Yesterday I <a href="https://twitter.com/shauninman/status/95199098965196801" title="twonder (v) to wonder aloud on Twitter">twondered</a> if there had been any developments in the browser space regarding linking directly to arbitrary elements. I wanted to link to a specific section of a page on a site I don&#8217;t maintain but that the author hadn&#8217;t anticipated linking to. The solution I <a href="https://twitter.com/shauninman/status/95200456380387328">proposed</a> was a jQuery-like syntax for a normal CSS selector added to a url as part of the hash.</p>

<p>Then <a href="http://meyerweb.com/">Eric Meyer</a> pointed me to this proposal for <a href="http://simonstl.com/articles/cssFragID.html">Using CSS Selectors as Fragment Identifiers</a> (co-authored by <a href="http://simonstl.com/">Simon St.Laurent</a>). </p>

<p>Almost exactly what I was looking for but still just a proposal. So I put together a simple Safari Extension called <a href="/assets/downloads/CSSFrag.safariextz">CSSFrag</a> that implements <code>#css()</code> selectors in url fragments (sans fallbacks). Then <a href="http://laurian.gridinoc.name/">Laurian Gridinoc</a> ported it to <a href="https://addons.mozilla.org/en-US/firefox/addon/cssfrag/">Firefox</a> as a restartless extension (<a href="https://github.com/Laurian/CSSFrag">source</a>). And then <a href="http://cheeaun.com/">Lim Chee Aun</a> ported it to a <a href="https://chrome.google.com/webstore/detail/iknlkmaapldbepbbhebanpfhenbeaddi">Chrome</a> extension (<a href="https://github.com/cheeaun/CSSFrag/">source</a>). Later, <a href="http://hasather.net/">David Hasather</a> ported it to an <a href="https://addons.opera.com/addons/extensions/details/cssfrag/0.2/">Opera</a> extension (<a href="https://bitbucket.org/hzr/cssfrag/">source</a>). Progress!</p>

<p>Download CSSFrag for <a href="/assets/downloads/CSSFrag.safariextz">Safari</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/cssfrag/">Firefox</a>, or <a href="https://chrome.google.com/webstore/detail/iknlkmaapldbepbbhebanpfhenbeaddi">Chrome</a>. Here&#8217;s an sample link to try once installed: Daniel Brown&#8217;s excellent <a href="http://danielbrown.vgpiano.com/audio.htm#css(a[href$=%22mp-act1.mp3%22])">Metroid Piano</a> covers. (Note that attribute selector values must be quoted as well as URI encoded). The best part is that even if you don&#8217;t have the extension installed the link still works.</p>

<h2 id="h2-authordesigned-versus-userdesigned-urls">Author-designed versus User-designed urls</h2>

<p>CSSFrags are not meant to replace more concise, author-designed urls. CSSFrags enable a site&#8217;s users to address specific sub-content that the site&#8217;s author may not have anticipated as being interesting. Think about user stylesheets and how they afford another layer of control above author-designed stylesheets. This was also the <a href="https://twitter.com/meyerweb/status/95544060118433792">intention of the original proposal</a>.</p>

<h2 id="h2-caveats">Caveats</h2>

<p>Like normal fragment identifiers, CSSFrags may not be able to jump to an anchored element if the page is modified by JavaScript that causes the document to reflow or otherwise modifies attributes. Not sure if there&#8217;s a sensible solution to that problem.</p>

<p>Because CSSFrags might rely on content or specific document structure they are considerably more volatile than &#8220;normal&#8221; links.
But, unlike a traditional broken link where a 404 results in missing content, a broken or unsupported CSSFrag only results in a loss of context, leaving the user to manually find the relevant element.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F07%2F25%2Fcssfrag&amp;seed_title=CSSFrag+Safari+Extension</link>
	<guid isPermaLink="false">1543@http://www.shauninman.com/</guid>
	<category>Collaborations</category><category>About</category><category>CSS</category><category>Web</category>
	<pubDate>Mon, 25 Jul 2011 13:25:00 GMT</pubDate>
</item>
<item>
	<title>Reply Reach</title>
	<description><![CDATA[<p>This morning Jesse Gardner <a href="https://twitter.com/plasticmind/status/76266139860221953">tweeted</a>:</p>

<blockquote>
  <p>When I&#8217;m writing an @reply, it would be cool to know how many of my friends would be seeing it in their feeds.</p>
</blockquote>

<p>Which reminded me of Eric Meyer&#8217;s <a href="http://meyerweb.com/eric/tools/followerlap/">Followerlap</a>. So for my morning mental calisthenics I whipped up a simple JavaScript bookmark that allows you to check your reply reach before hitting the Tweet button. </p>

<p>Just drag this <a href="javascript:(function(){$('textarea.twitter-anywhere-tweet-box-editor:focus').each(function(){var%20t=this.value;if(m=t.match(/@([a-z0-9]+)/i)){var%20r=m[1];var%20s=$.trim($('#screen-name').text());var%20u='http://meyerweb.com/eric/tools/followerlap/?u1='+s+'&amp;u2='+r;window.open(u);return%20false;};});})();" onclick="alert('Drag me to your bookmarks bar!'); return false;">Reply Reach</a> link to your bookmarks bar and give it a click the next time you hit that reply link.</p>]]></description>
	<link>http://shauninman.com/feeder/?FeederAction=clicked&amp;feed=Complete&amp;seed=http%3A%2F%2Fwww.shauninman.com%2Farchive%2F2011%2F06%2F02%2Freply_reach&amp;seed_title=Reply+Reach</link>
	<guid isPermaLink="false">1541@http://www.shauninman.com/</guid>
	<category>JavaScript</category>
	<pubDate>Thu, 02 Jun 2011 13:02:00 GMT</pubDate>
</item>
</channel>
</rss>
