<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vectorform Labs</title>
	<atom:link href="http://labs.vectorform.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.vectorform.com</link>
	<description>Showcasing Vectorform&#039;s latest and greatest experiments.</description>
	<lastBuildDate>Tue, 17 Apr 2012 20:23:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Introducing Your Brand to a Metro Style Windows 8 App</title>
		<link>http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/</link>
		<comments>http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 01:32:17 +0000</pubDate>
		<dc:creator>Josh Maldonado</dc:creator>
				<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Visuals]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=2098</guid>
		<description><![CDATA[Designing Metro style apps on Windows 8 can be challenging just like any other new platform.  It is especially challenging on a platform that’s so radically different than its predecessors. The most fundamental part about abiding by Metro standards is to not lose your brand’s personality and unique elements in the process.  Metro as a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/chrome-4/" rel="attachment wp-att-2149"><img class="alignnone size-full wp-image-2149" src="http://labs.vectorform.com/wp-content/uploads/2012/04/Chrome3.jpg" alt="Windows 8 Brand Intro Image" width="640" height="300" /></a></p>
<p>Designing Metro style apps on Windows 8 can be challenging just like any other new platform.  It is especially challenging on a platform that’s so radically different than its predecessors. The most fundamental part about abiding by Metro standards is to not lose your brand’s personality and unique elements in the process.  Metro as a design style should never replace your brand as a whole.</p>
<p>Using Metro as a foundation along with your brand’s style guide is key.  It’s a common misconception that every app will look the same if you’re using Metro properly.</p>
<p><span id="more-2098"></span></p>
<p>Beyond the squares and tiles there is a well-established grid.  Beyond Segoe there’s the concept of a well-designed typographical-based layout.  Utilize your brand’s rhetorical elements and unique shapes.  Although Metro standards emphasize ‘content over chrome’ it doesn’t mean to throw out chrome altogether.  It means to use it sparingly and only when it makes sense.</p>
<p>A brand creates valuable emotional connection between a customer and a product or service.  The components of a brand will leave lasting impressions on its customers and this is what makes the product unique.  These components shouldn’t be thrown out to make room for Metro standards; they should simply be re-considered.  Brand elements such as messaging and voice, typography, rhetorical elements, logo usage and placement, color schemes make up the personality and identity of the brand.  They should be leveraged to differentiate the company in the marketplace.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/brandelements/" rel="attachment wp-att-2100"><img class="alignnone  wp-image-2100" src="http://labs.vectorform.com/wp-content/uploads/2012/04/BrandElements.jpg" alt="Example of Brand Elements" width="620" height="316" /></a></p>
<p>So how do you find the perfect marriage between Metro and your brand? The answer is to revisit your brand’s core fundamentals.  Very few brands have “iPhone style app bar” as a core brand principle. Most brands focus on emotion through color and photography, typographical hierarchy, and a mission statement of their intended user perception. Returning to these key elements is the best way to adapt to the new Windows platform and will produce extremely compelling apps. So where do you begin when thinking about returning to the basics?</p>
<p><strong>TYPOGRAPHY</strong></p>
<p>First of all, you don’t HAVE to use Segoe for everything.  Segoe is ideal for large bodies of text or for captions in the same way you would use a web safe font (pre CSS3) on a web page.  Use brand specific fonts in areas that will showcase your brand, like for headings.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/headings/" rel="attachment wp-att-2101"><img class="alignnone  wp-image-2101" src="http://labs.vectorform.com/wp-content/uploads/2012/04/Headings.jpg" alt="Example of Typography in Headings" width="620" height="316" /></a></p>
<p>Metro favors the use of typography over buttons with gradients and strokes. The list view is a common Metro section layout that features typography really well. This could also be a place to feature your brand’s unique typefaces.  Although brand fonts may be used, it’s a good idea to abide by the metro <a title="Windows 8 Metro Type Ramp" href="http://msdn.microsoft.com/en-us/library/windows/apps/hh700394.aspx" target="_blank">type ramp</a>.  It’s flexible and helps keep the integrity of Metro while providing options.</p>
<p><strong>PLAY WITH THE GRID</strong></p>
<p>Don’t get stuck on the simple square grid layouts.  If you are using the hub and spoke navigation model and developing a panorama view as your hub, make it interesting. Use different sizes to indicate importance or what ever is relevant to what you’re trying to convey.  Use compelling imagery in your tiles; think about weight, proximity and color usage.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/gridall/" rel="attachment wp-att-2102"><img class="alignnone  wp-image-2102" src="http://labs.vectorform.com/wp-content/uploads/2012/04/GridALL.jpg" alt="Examples of Grid" width="620" height="349" /></a></p>
<p>You don’t even have to use the hub and spoke model if your experience doesn’t require it. Explore other navigation models.</p>
<div id="attachment_2103" class="wp-caption alignnone" style="width: 630px"><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/web/" rel="attachment wp-att-2103"><img class=" wp-image-2103  " src="http://labs.vectorform.com/wp-content/uploads/2012/04/HubAndSpoke-01.jpg" alt="Example of Hub and Spoke Model" width="620" height="370" /></a>
<p class="wp-caption-text">Hub and Spoke Navigation Model</p>
</div>
<p><strong>KNOW WHEN ‘CHROME’ HELPS</strong></p>
<p>I LOVE the concept of content over chrome.  Sometimes designers (myself included) will over design things to the point where there are too many bells and whistles, even if strategically placed.  These additional elements often get in the way of what the designer is actually trying to convey.  The first rule of Metro standards is content over chrome; it is meant to embody the concept that less is more. Be selective of what needs extra visual treatment to support your end goal. Unfortunately some of the apps that have early adopted this platform have a sea of black text that could be easily broken up by supporting visual elements or compelling imagery.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/article/" rel="attachment wp-att-2104"><img class="alignnone size-full wp-image-2104" src="http://labs.vectorform.com/wp-content/uploads/2012/04/Article.jpg" alt="Example of Details Page" width="640" height="360" /></a></p>
<p>It is especially evident on displays with higher resolutions or different aspect ratios.</p>
<p>This is why it takes a skilled designer to work on a Windows 8 app.  How do you find the perfect balance between too much chrome and too little? Chrome should be used sparingly and only when it makes sense.</p>
<p>A great place to use a small amount of chrome is to differentiate between list items that have multiple data types. A simple background shift between each item could help the user identify each item better.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/snapviewlist/" rel="attachment wp-att-2105"><img class="alignnone size-full wp-image-2105" src="http://labs.vectorform.com/wp-content/uploads/2012/04/SnapViewList.jpg" alt="Example of List Items Separated By Chrome" width="640" height="300" /></a></p>
<p>Is this adding a little bit of chrome? Yes. Is it still keeping the content king? Yes. “Content OVER chrome”…not “Content ONLY.” The key is to eliminate the problem where people get frustrated by all the unnecessary UI that smothers the content they are looking for.</p>
<p>If your brand is recognizable through unique forms, patterns, and rhetorical elements, use them appropriately.  Don’t get stuck on squares.  Introduce diagonals or circles in the background or within a content tile to indicate fresh content or to distinguish one element from another.</p>
<p><a href="http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/rhetoricalelements2/" rel="attachment wp-att-2106"><img class="alignnone size-full wp-image-2106" src="http://labs.vectorform.com/wp-content/uploads/2012/04/RhetoricalElements2.jpg" alt="Example of Rhetorical Elements used in Design" width="640" height="300" /></a></p>
<p>There will be times when a simple square will be enough but if you’re trying to create a unique experience, your layouts and applications should not be templates.</p>
<p>These methods of retaining brand voice through layout design are key for having a successful and memorable app. Metro standards guide the design to be grid centric, have beautiful type and keep the content front and center.  The same can be said about designing for any platform.  Remembering this eliminates the theory of: Metro = squares and lists.</p>
<p>Despite some criticism, Windows 8 is an excellent playground for designers looking to create unique and functional experiences.  It also is a great place for a brand to shine.  As long as Metro is used as a foundation rather than a template to just swap in text and background images, a designer has the opportunity to create unique brand experiences that are both compelling and easily digestible.  Metro is rooted in some of the best design principles in history and emphasizes good guidelines to keep in mind during the design process.</p>
<p>To view this <a title="Building Great News Apps on Windows 8" href="http://msdn.microsoft.com/en-us/library/windows/apps/hh868272.aspx" target="_blank">sample project</a> and to learn more about building great Metro apps please visit: <a title="Design Windows" href="http://msdn.microsoft.com/library/windows/apps/hh779072" target="_blank">design.windows.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/04/introducing-your-brand-to-a-metro-style-windows-8-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Impressions of Windows 8 &#8211; Part 2 of 2</title>
		<link>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-2-of-2/</link>
		<comments>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-2-of-2/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 11:30:33 +0000</pubDate>
		<dc:creator>Filip Skakun</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1928</guid>
		<description><![CDATA[This is the second part of my impressions of Windows 8. You can read the previous part here. The Impressions Windows 8 and the Cloud Using Windows 8 on a Slate Using Windows 8 on a Laptop Using Windows 8 on a Desktop Desktop IE vs. Metro IE Frustrations of Being an Early Adopter Windows [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/windows_8_logo/" rel="attachment wp-att-1962"><img class="alignnone size-full wp-image-1962" src="http://labs.vectorform.com/wp-content/uploads/2012/04/Windows_8_logo.png" alt="" width="605" height="128" /></a></p>
<p>This is the second part of my impressions of Windows 8. You can read the previous part <a href="http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/">here</a>.</p>
<p><span id="more-1928"></span></p>
<h2>The Impressions</h2>
<ol>
<li><a href="#cloud">Windows 8 and the Cloud</a></li>
<li><a href="#win8onslate">Using Windows 8 on a Slate</a></li>
<li><a href="#win8onlaptop">Using Windows 8 on a Laptop</a></li>
<li><a href="#win8ondesktop">Using Windows 8 on a Desktop</a></li>
<li><a href="#twoies">Desktop IE vs. Metro IE</a></li>
<li><a href="#frustrations">Frustrations of Being an Early Adopter</a></li>
</ol>
<p><a name="cloud"></a></p>
<h2>Windows 8 and the Cloud</h2>
<p><a title="Windows 8 in the Cloud by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/7039000349/"><img src="http://farm8.staticflickr.com/7137/7039000349_a3b5fd79d4.jpg" alt="Windows 8 in the Cloud" width="352" height="279" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>Metro style apps are limited in their ability to access system resources such as files in arbitrary locations on the disk. This though has been mostly true for a while now, since Windows Vista introduced user access control. This is a good thing and makes managing your files easier, but it is also a stepping stone to the future in which we will increasingly rely on the cloud to store our files. Local disks will be used as application storage and local cache of the data we currently use or might need when offline, but what we already see in online backup and file sharing solutions like <a href="http://www.carbonite.com/en/">Carbonite</a>, <a href="http://www.apple.com/icloud/">iCloud</a>, the <a href="http://www.pcworld.com/article/252676/is_google_drive_coming_soon.html">rumored Google Drive</a>, <a href="http://www.dropbox.com">Dropbox</a> and <a href="http://www.skydrive.com">SkyDrive</a> — is bound to slowly become the primary copy of our data — secured from accidents, hardware failures and hackers better than our own devices while allowing to conveniently access our data from any device.</p>
<p>Windows 8 adds built-in user and developer support for SkyDrive integration. You can sign into Windows with your (Windows) Live account, which then automatically syncs your profile settings across all Windows 8 devices. Apps can easily use roaming settings that are synchronized between all the devices. Internet Explorer shows the same bookmarks for — again — all your devices. Your data travels with you everywhere taking away the pain of having to micromanage your documents, settings and any other data, and copying it back and forth. I can&#8217;t wait to dump all my backup drives, thumb drives and stop worrying about backing up and creating many copies of the same data on my phone, slate, laptop, desktop and XBOX, at home, in the office and on the road.</p>
<p><a name="win8onslate"></a></p>
<h2>Using Windows 8 on a Slate</h2>
<p><a title="My Windows 8 Workstation Setup - a Laptop and a Slate with Full-Size Keyboard, Mouse and HD Display by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/7039000139/"><img src="http://farm8.staticflickr.com/7214/7039000139_2252dd5c31_b.jpg" alt="My Windows 8 Workstation Setup - a Laptop and a Slate with Full-Size Keyboard, Mouse and HD Display" width="620" height="317" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>The tablet I use is a custom version of the <a href="http://www.amazon.com/Samsung-XE700T1A-A03US-11-6-Inch-Slate-128/dp/B005OUQ9WO">Samsung Series 7 Slate</a> that was given out to developers by Microsoft at the <a href="http://www.buildwindows.com/">Build conference</a>. This is my work machine and I mostly use it with an external 24-inch monitor and a basic full size keyboard. It is slightly bigger than the iPad — at 11.6-inch vs. 9.7-inch and also a bit heavier and featuring a built-in fan. Not exactly an iPad competitor since it is about twice the price, but with my setup I can use it for developing apps on a big screen with all the peripherals I want to connect to it, and when needed I can just pick it up from the dock and use it the same way I would use an iPad. With smaller devices getting more powerful while the computing tasks have not become much more demanding since the popularization of video or HD video especially — I can easily imagine many people in the future might choose to use a Windows tablet that they can carry with them to do some lightweight computing or consumption and dock it anywhere when they need to do something more demanding like programming. This is not something that you can do today with an iPad and <a href="http://www.wp7connect.com/2011/09/15/reason-4585671-why-windows-8-is-better-than-the-ipad/">this popular photo</a> shows best how an iPad relates to a PC — being just an accessory. Windows tablets might get a lot better appeal as something that is not only a cool expensive gadget, but also a tool to be used for more serious tasks such as making money.</p>
<p>I have not had a chance to use the tablet much in slate scenarios that iPad rules today — mostly because this is a work machine and it sees majority of its use in developing and prototyping new Windows 8 apps but also because I am not a heavy iPad user. I really prefer to have a mouse and keyboard, ideally a full-sized one to use a computer comfortably. I use an iPad occasionally to play a game, check mail, or look at some other app when I am lying in bed or sitting on a couch and the iPad happens to be within reach. My iPad is mostly used by my kids and I can see great educational potential of such devices having seen my daughter who is beginning to read before turning four year old. I do not think the iPad is the main reason she is doing well, but I am sure it helps and similar devices will continue to help kids learn more quickly than was common when I was a kid. Windows 8 has great potential here. I think the user experience on the Windows tablet is better. The current selection of apps available is limited compared to iPad which had a head start, but this will change very quickly. There are thousands of apps available on iOS, but not so many of them are great and it is certain that most of the great apps will also come out for Windows 8 soon, possibly with improvements over their iOS or Android counterparts while new great apps will often start appearing on Windows first, since this is reportedly also an easier platform to develop for.</p>
<p>One area where Apple has ruled without much successful competition is hardware design. The iPad at prices starting at $399 and being most fashionable gadget today seems hard to beat having resisted the offensive of various crops of Android slates and only losing in lack of a cheap version under $200 where Android-based devices rule, but just as the iPhone seeing strong competition from Android-based phones, the iPad will not last forever as the only contender in the slate game. Just as we are beginning to see emergence of great Windows Phone devices such as the <a href="http://news.cnet.com/8301-1035_3-57404464-94/htc-titan-ii-officially-coming-to-at-t-april-8/">HTC Titan II</a> or the ($99!) <a href="http://news.cnet.com/8301-1035_3-57404235-94/at-t-to-sell-nokia-lumia-900-for-$100-on-april-8/?tag=mncol;txt">Nokia Lumia 900</a>, I think we might see competitive Windows 8 slate devices from Samsung or Nokia that might compete in price as well as design with the iPad while potentially also being full-featured desktop PC replacements, which cannot be said of the iPad.</p>
<p><a name="win8onlaptop"></a></p>
<h2>Using Windows 8 on a Laptop</h2>
<p><a title="Windows 8 on a Laptop by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/6892904928/"><img src="http://farm8.staticflickr.com/7253/6892904928_173be2a507_b.jpg" alt="Windows 8 on a Laptop" width="620" height="466" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>My laptop is a now 1.5 year old Lenovo T410s with multi-touch screen, a 160GB SSD drive and 8GB RAM. Perhaps not a typical laptop due to the touch support, although possibly a much more common setup in the future when the touch-friendly Windows 8 gets released (I am keeping an eye out for the <a href="http://www.theverge.com/2012/1/9/2693650/lenovo-ideapad-yoga-a-windows-8-laptop-that-bends-backwards-into-a">Lenovo Yoga</a>, an ultrabook with a touchscreen that also converts to a tablet!). Installation of Windows 8 Consumer Preview on the laptop took around 10-15 minutes, so does upgrade from an older version which I am happy to see also kept all my installed applications and settings, which is great, since it usually takes me hours if not days to install all the software I use on a fresh install of Windows and I believe older versions of Windows were not able to port these over during upgrade.</p>
<p>Except for the previously mentioned 8s cold boot time, the system also resumes from sleep in under 2s, seems to manage battery better and run more quietly. There are no driver problems except for the missing touch input driver I talk about <a href="#frustrations">later</a> that should not be common since this is an uncommon type of device. Also, I expect Windows 8 to mostly be used on new devices while I also recommend trying to install it on older ones, since it brings so many improvements over Windows 7. Have I forgotten to mention Windows 8 also uses less memory? This means leaving more of it to applications, and practically lower hardware requirements than Windows 8 or Vista.</p>
<p>I do not use the touch screen much right now since without the proper driver it does not work too well, although I can vouch for the convenience of having a touch screen on a laptop. Any time I can&#8217;t find a mouse I can just touch the screen. Scrolling web pages with fingers is much more natural than scrolling with a mouse, so is browsing and consuming a lot of other types of documents and content. Drawing is easier with a finger than a mouse, so is navigating maps and&#8230; well, developing multi-touch software. It might also help reduce the risk of repetitive stress injuries if you often switch between different input devices depending on which one feels most comfortable at a particular time. With Windows 8 using the OS with touch is also easier than with any other OS out there.</p>
<p><a name="win8ondesktop"></a></p>
<h2>Using Windows 8 on a Desktop</h2>
<p><a title="Windows 8 on Desktop by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/6892904952/"><img src="http://farm8.staticflickr.com/7185/6892904952_36a7570406_b.jpg" alt="Windows 8 on Desktop" width="800" height="600" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>For some reason installing Windows 8 on my desktop was quite a bit harder than on my laptop or the tablet. Possibly a driver issue caused the screen to go black during the installation multiple times and while I believe it was only a problem of display — I had to restart installing the OS multiple times before I managed to reach the point where the installation would progress without my input, so even when the screen went black, restarting half an hour later showed it booting to Windows 8.</p>
<p>I have no touch screen display on my desktop, although I cannot wait to start seeing affordable 24&#8243; or bigger true multi-touch screens which I hope will start showing up soon when Windows 8 comes out. Using touch on a desktop screen is not as natural as on a slate and not even as convenient as on a laptop, but I keep getting into situations when I touch the screen and I am surprised it does not work. Touch input really becomes a natural (even if only alternative) way to interact with a computer once you have used it for a while. It is not the best way to input text or event to play most types of games I like, but it is as natural as mouse and keyboard in some scenarios.</p>
<p>Overall having installed all the applications I used to use in Windows 7 to Windows 8 — my desktop is now mostly used from Windows 8, although I have it installed in dual boot mode just in case. The machine was put together with my very own hands and as far as I remember is an Intel Core i5-powered, 4GB RAM, 2+2+1+1TB HDD with 3-4 year old AMD/ATI Radeon graphics and since installation functions mostly without issues. It does sometimes refuse to shut down when I tell it too, but on the other hand, it has leverage over Windows 7 in that it turns of unused hard drives reducing the jet-like noise that the machine used to continuously generate before turning it into a <a href="http://en.wikipedia.org/wiki/Silent_PC">quiet PC</a>.</p>
<p><a name="twoies"></a></p>
<h2>Desktop IE vs. Metro IE</h2>
<p><a title="Metro Internet Explorer vs. Desktop Internet Explorer by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/7039000499/"><img src="http://farm8.staticflickr.com/7259/7039000499_323549a5c7_z.jpg" alt="Metro Internet Explorer vs. Desktop Internet Explorer" width="620" height="232" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>I see a good reason for having two different browsing experiences. Web applications look beautiful in a browser without chrome. Using a computer without a keyboard and mouse is very limiting in the number of things you can do at a time, so looking at one website at a time makes most sense and seeing all the tabs that are open at the same time is not as useful. In desktop view I expect more power, a HUD of sorts that will allow me to orient myself better in the dozens of tabs that I tend to keep open in a browser at the same time, switching between different apps and so on. The Metro experience is more focused on one thing. Not allowing for browser plugins in the metro experience makes sense if it saves battery and helps push the web technologies forward, although might be annoying sometimes if you know there is a version of IE that can run on desktop that does run both Flash and Silverlight. I really do like the sharing of bookmarks between all my machines. Perhaps the desktop version could actually look and work more like the Metro version does and I believe it was left alone mostly so that the team could focus on the Metro version. I think maybe by the time Windows 8 is released or soon after — we might see the desktop version of IE modified to show no chrome by default until the user right clicks needing to type in a new address or switch a tab with a mouse. The web truly looks better with no chrome.</p>
<p>In fact the web looks so good without chrome that future web applications will likely become more powerful not unlike today&#8217;s desktop applications and will replace them in many scenarios while users will not see a difference. Currently you can develop applications for Windows 8 using HTML and JavaScript which are the same tools you use for developing web pages and web apps. Microsoft augments the framework allowing developers to create good looking and nicely animated Metro style apps with full access to the OS fairly easily but it also means that these applications will not run on any other platform and will not be easy to port either — it merely uses some of the familiar skills that today&#8217;s web developers can use to develop Windows 8 applications. As the tools continue to improve, doing similar applications should become as feasible for other platforms too. This in turn will allow for creation of a single application for all platforms having to only take into account the screen size, resolution, input methods and system features when creating different versions of the experience, but that I believe is still in the future farther off.</p>
<p><a name="frustrations"></a></p>
<h2>Frustrations of Being an Early Adopter</h2>
<p><a title="Frustration of an Early Adopter by Filip Skakun, on Flickr" href="http://www.flickr.com/photos/37567720@N05/7039000517/"><img src="http://farm8.staticflickr.com/7248/7039000517_3d5121bc98.jpg" alt="Frustration of an Early Adopter" width="90" height="161" /></a><br />
© <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>Not everything is rosy if you are trying out a new operating system early. The list of things I had to suffer contains the following:</p>
<ol>
<li>The old N-Trig touch input drivers for my laptop do not work on the current build of Windows 8. There was a workaround to use them in Developer Preview, but it does not work anymore. Windows 8 class drivers for touch seem to work at first — I can see touch input visualizations for my fingers, but they are very shaky and I can&#8217;t tap on buttons, etc. Using touch to scroll or unlock the screen still works though. The new <a>drivers</a> only showed up on N-Trig&#8217;s website moments ago today.</li>
<li>TurboTax complained for a moment that my operating system was not supported even when I used it in Chrome. It seems to have accepted it now though.</li>
<li>The VPN client I use does not work with Windows 8 yet and it seems like there might be a workaround using a generic VPN client application, but I have not been able to get it to work yet, so when I need to work from home — I am a bit disconnected since I can&#8217;t access some internal company resources, although I am sure if I really had to, I could get it to work even now with the workaround.</li>
<li>The WinKey+S shortcut that used to work with OneNote to grab a screenshot of a selected piece of the screen did not work at first. I used to use it quite a lot, so I was unhappy when I saw it not working. Fortunately it came back &#8211; possibly after a reboot which is an uncommon event in Windows 8&#8230;</li>
</ol>
<p>These problems and a few others have been minor annoyances, but I am sure they will be resolved by the time Windows 8 is released and overall even now are outweighed by the improvements you get from the new OS.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-2-of-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Impressions of Windows 8 &#8211; Part 1 of 2</title>
		<link>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/</link>
		<comments>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 14:20:34 +0000</pubDate>
		<dc:creator>Filip Skakun</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1861</guid>
		<description><![CDATA[I have been using the Windows 8 Preview For six months now &#8211; the Developer Preview since its public release in September and more recently, the Consumer Preview that was made available in February. I have used Windows 8 on a tablet, a touch screen laptop and an old desktop and the experience has been [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/windows_8_logo/" rel="attachment wp-att-1962"><img src="http://labs.vectorform.com/wp-content/uploads/2012/04/Windows_8_logo.png" alt="" width="605" height="128" class="alignnone size-full wp-image-1962" /></a></p>
<p>I have been using the Windows 8 Preview For six months now &#8211; the Developer Preview since its public release in September and more recently, the Consumer Preview that was made available in February. </p>
<p>I have used Windows 8 on a tablet, a touch screen laptop and an old desktop and the experience has been good on all of these platforms. I have used it for anything from developing Windows 8 Metro style apps, through typical Office applications scenarios, browsing the internet, playing games, listening to Spotify, instant messaging etc. What I have not used it much for actually is to run Metro style apps, except for the ones I was developing myself, since there are not so many available yet (around 100) and the ones available do not fit into my daily use of a tablet or computer.</p>
<p>I have been using most versions of Windows available in the past 20 years or so. I have also been using an iPad for a few months now. <em>I think Windows 8 is going to be huge&#8230;</em></p>
<p><span id="more-1861"></span></p>
<h2>The Impressions</h2>
<ol>
<li><a href="#desktop">The Desktop</a></li>
<li><a href="#startbutton">The (Missing) Start Button</a></li>
<li><a href="#startscreen">The Start Screen</a></li>
<li><a href="#metroapps">Metro Style Apps</a></li>
<li><a href="#appstore">Windows Marketplace</a></li>
<li><a href="#nextup">Next Up</a></li>
</ol>
<p><a name="desktop"></a></p>
<h2>The Desktop</h2>
<p><a href="http://www.flickr.com/photos/37567720@N05/6892904866/" title="Desktop by Filip Skakun, on Flickr"><img src="http://farm8.staticflickr.com/7078/6892904866_c190ecfcef.jpg" width="500" height="313" alt="Desktop"></a><br />&copy; Screenshot by <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>I am a developer and I spend most of my time using keyboard Visual Studio, Chrome &amp; Internet Explorer, Paint, <a href="http://www.ghisler.com/">Total Commander</a>, Notepad, Windows Explorer, etc. <em>Desktop is my world. It has not changed&#8230;</em></p>
<p>Well, it has changed in some ways — now Windows boots up in eight seconds instead of 8 minutes, the Start button is a lot smaller and completely transparent and all the corners of the desktop are now buttons of sort even though they are invisible. The Windows Explorer uses a Ribbon interface now, if you use two or more monitors — you now get the taskbar on all of them without the need for third party add-ons, the file copy menu looks nicer now and so does the task manager. There are some more advanced features I have not used yet, and I am sure thousands of imperceptible minor changes  but overall, nothing has changed in the way I use Windows since I switched from Windows 7 to Windows 8. I only get a feeling like here and there, this thing or the other works better — IE 10 is a bit better than IE 9, Windows installs in like 10 minutes. Opening an ISO file in Windows Explorer displays its contents as if it was a folder while also mounting it as a virtual drive — possibly opening us up to the future with no CDs or DVDs required to install any (even legacy) desktop applications or games with no need for third-party tools. There is a built-in viewer for PDF files, so you don&#8217;t need to install the 50MB beast from Adobe that requires a new update every day. There are things like these scattered all over the place.</p>
<p>One very minor issue that sometimes hits me in the desktop is that Chrome displays tabs starting from the top left corner of the screen, so sometimes instead of switching to the first tab, I switch to another app. Maybe one more reason to switch back to IE?</p>
<p><a name="startbutton"></a></p>
<h2>The (Missing) Start Button</h2>
<p><a href="http://www.flickr.com/photos/37567720@N05/7039000021/" title="Windows 8 Start Button by Filip Skakun, on Flickr"><img src="http://farm8.staticflickr.com/7130/7039000021_516f5f3e4f.jpg" width="255" height="176" alt="Windows 8 Start Button"></a><br />&copy; Screenshot by <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>There is no visible start button now. There is a <a href="http://www.youtube.com/watch?v=v4boTbv9_nU">popular video</a> that is making rounds on the internet that is trying to prove that this is a big usability problem, but is it a problem really? When I first saw the desktop without the button I felt like there was a disconcerting void where something familiar used to exist for almost 20 years now. Personally, I see no benefit in getting rid of the button — the space savings are really minor compared to potential problems with usability, but once you start using it — you get used to it missing really quickly. You can still click the bottom left corner to bring up the Start Menu — the difference being you now have to move your mouse cursor to the very corner of the screen. In terms of everyday usability, it is just as easy if not marginally easier than what you might have been doing before — if you were like me, trying to point at somewhere near the center of the old start button before clicking. The problem might be if you are one of the few people who move their taskbar somewhere else than the bottom of the screen, which in previous versions of Windows also moved the start button. (I would argue though that in these cases you moved the taskbar to rearrange your space and having the start button move with it was not as crucial for you.)</p>
<p>Coming back to casual Windows users confused about the lack of the button — I am sure Microsoft will at least introduce some cues to indicate where to move the mouse when you first switch to desktop, the same way they have done before to educate users on the Start button in Windows or the glowing Microsoft Office Button that was introduced with the Ribbon in Office 2007 to open the Backstage. I am sure people will first be surprised when they do not see the button there, but many will be happy to get rid of an unnecessary ornament on the screen, especially if they are like me and already use the start button on their keyboards instead of fiddling with the mouse.</p>
<p>I would speculate that Microsoft might give in and bring back the start button to address the critical comments. Perhaps the only reason it is gone now is as an experiment and due to lack of time to switch to a design with a new logo. It is also possible that they will get rid of Aero Glass and make the desktop chrome more flat and Metro when they finally release Windows 8. Also — since they make corners and borders of the screen such important UI elements — they could also make the taskbar auto-hide by default to reduce unnecessary chrome.</p>
<p><a name="startscreen"></a></p>
<h2>The Start Screen</h2>
<p><a href="http://www.flickr.com/photos/37567720@N05/7039000185/" title="Windows 8 Start Screen Tiles and Windows Phone 8 Start Screen Tiles by Filip Skakun, on Flickr"><img src="http://farm8.staticflickr.com/7225/7039000185_4179132c76.jpg" width="500" height="269" alt="Windows 8 Start Screen Tiles and Windows Phone 8 Start Screen Tiles"></a><br />&copy; <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>There is no Start Menu as we know it in Windows 8. It was replaced with the Start Screen, which is the most visible change in Windows 8. It takes design ideas from Windows Phone, introducing large active tiles instead of a grid of dead small icons with tiny labels seen on other phones or desktop UIs. Instead of a small menu in the corner of the screen that you had to squint at, you have the whole screen to fill with easily readable tiles that serve the same purpose — to launch applications, but also display additional information that allows you to get information you might be looking for without even starting an app. I think this is a good idea. Gone is a multi-level-nested hierarchy of app folders that made things discoverable if you went on exploring the menu, but not really useful for starting applications. You can still access all installed applications in the Start Screen by searching or clicking on the &#8220;All apps&#8221; menu.</p>
<p>Since Windows 7 I would usually only start applications I pinned to the taskbar or less frequently used ones that I had pinned inside of the Start Menu. This still works, but now instead of having them pinned in the Start Menu, I have them pinned on the Start Screen with some more options to rearrange them. If I had to launch an application only once — I used to just type its name in the Start Menu and a link would show up. It still works on the Start Screen, only it is easier to read. There is no important scenario where having a Start Menu showing up in a corner of the screen would work better than having the big Start Screen that grabs your entire attention on the task of finding an application to run.</p>
<p>Will the old Start Menu be available as an option? I think it is possible but not likely. It seems like the Start Screen has already made it to Windows Server 8 too now, so although its design was possibly driven by the consumer version of Windows, it works just as well on the server. The often repeated comment that this could be an option for enterprise deployments to save on the costs of user education does have some sense, but I do not think it is correct. Changing an OS is always a change and users will always need to learn something new. If you let enterprises upgrade to Windows 8 while keeping the old Start Menu — how about users who get into Windows 8 at home, use the Start Screen and then go to work and see the Start Menu? That would also require education I am sure. Also — live tiles would not work inside of the start menu, so how about disabling Metro style apps altogether? Well, but about the case when some applications start becoming available only in Metro Style? Also — I am sure it is Microsoft&#8217;s goal to have as many people using Metro style apps as possible, since it brings Microsoft money, so they would not pass on that. Then there is also the problem of maintaining two parallel versions of an interface serving the same purpose. It has been historically possible to switch some things in Windows to how they were — e.g. in Windows 7 you can disable combining the tab buttons in the taskbar and switch to small buttons &amp; labels — the same way it had worked since Windows 95. I do not really recommend doing that though since the new Windows 7 version is better. I am sure few people know about it being possible and I believe it has happened under different management. Now with Windows being ruled by Steven Sinofsky and his team who forced the world to use Office with the Ribbon and did away with the old toolbars — I don&#8217;t think it is likely to leave two competing versions of quite complicated UI — that would be just too difficult to maintain.</p>
<p>There is one valid criticism I have heard about the Start Screen — if you press spacebar once — you select a tile, if you press it again — you unpin it. This seems like a dangerously simple way to accidentally get rid of your pinned tiles and for millions of support calls to Microsoft if this does not change before release.</p>
<p><a name="metroapps"></a></p>
<h2>Metro Style Apps</h2>
<p><a href="http://www.flickr.com/photos/37567720@N05/6892904824/" title="Windows 8 Metro Style App sample - Flixster showing the Expendables 2 page by Filip Skakun, on Flickr"><img src="http://farm8.staticflickr.com/7182/6892904824_67d3d830cb.jpg" width="500" height="313" alt="Windows 8 Metro Style App sample - Flixster showing the Expendables 2 page"></a><br />&copy; Screenshot by <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p>With Windows 8 Microsoft is adding a completely new technology for developing software. The new framework is called Windows Runtime and while the old WinAPI and related technologies layered on top of it are still available for developing desktop applications, Windows Runtime (or WinRT in short) is required for developing the new Metro style apps. The new framework and applications are sandboxed which means they have limited access to system resources and other applications installed on the computer which is a requirement to allow for a trustworthy app store where developers can easily publish apps and users can easily buy them at very reasonable prices.</p>
<p>The new technology limits applications developed for Windows from causing harm, but it does not really limit them from using the full processing power of the machine and Microsoft has learned their lesson from Windows Phone where — especially initially — developers had very limited access to the features of the devices making a lot of the more interesting applications that were available for iOS or Android devices impossible to implement on Windows Phone. Developers can create these new applications using lowest level, close-to-the-metal native technologies like DirectX while also having access to very popular and productive languages like C#, Visual Basic and JavaScript. The more liberal access to the features of the device compared to Windows Phone allows for a wide range of new classes of applications to be developed. Based on the rumors of the next Windows Phone sharing the core components with Windows 8, I am also expecting the next crop of Windows Phone applications to have access to many of these features and languages giving Windows Phone a bigger chance at growth and competitiveness against iOS and Android ecosystems.</p>
<p>Metro style apps on Windows 8 can be developed using C# and XAML, the same technologies used in most Windows Phone applications — the difference being that they use WinRT instead of Silverlight. Although from a developer&#8217;s view there is very little difference between these two platforms and WinRT being a lower level platform than Silverlight has potential for better performance as was shown in <a href="http://advertboy.wordpress.com/2012/01/15/a-shimmering-wall-of-sequins-to-compare-winrt-xaml-silverlight-5/">an article by Jose Fajardo</a> (who is one of the more known experts writing about WinRT).</p>
<p>Metro style apps have features that are already familiar to Windows Phone users — such as live tiles and Metro design language. These things are evolving though, and becoming more powerful in Windows 8. Live tiles can be made even richer than in Windows Phone 7 and controls in the Metro user interface are evolving to be more usable in both mouse &amp; keyboard and touch scenarios. Implementation of fluid transitions is now easier than ever before with built-in animation and transition libraries making it a lot easier to create a Metro style app that shines.</p>
<p>The XAML Disciples – a group of expert XAML developers that is made up of the early adopters and experts of WPF and Silverlight — seem to have mostly negative thoughts or no interest (<a href="http://groups.google.com/group/wpf-disciples/browse_thread/thread/641b1643913936a3">[1]</a>, <a href="http://joshsmithonwpf.wordpress.com/2012/03/20/does-anyone-actually-care-about-winrt/">[2]</a>) in the new technology. It seems like this comes mostly from lack of trust in the future of Windows or lack of applicability for the typical types of enterprise projects they are used to working on, or weariness after having experienced small changes between a series of similar frameworks coupled with limited interest expressed from Microsoft&#8217;s side in further development of WPF and Silverlight. Microsoft instead seems to focus on developing a new development framework for every new scenario that comes up, i.e. WPF &#8211; being the first framework for developing rich applications for Windows, Silverlight being its version with a promise of being cross platform compatible or a Flash killer, Silverlight for Windows Phone being its yet another flavor and WinRT&#8217;s XAML framework being yet another take on it that is being rewritten for Windows 8.</p>
<p>While I understand these pains, I disagree with the criticism. Each new platform is a bit different and requires a different approach, i.e. sandboxed environment required for running apps on the web or hosting in app stores is not really available in WPF. WPF is also too heavy to run on the web. The interoperability of WinRT and improvements in implementation in Silverlight and then WinRT are also important reasons for rewriting the framework. Also you have to appreciate how little you need to learn to switch to a new XAML-based technology after you have already mastered one. WPF and Silverlight are also in most ways feature complete and Microsoft has likely reached diminished returns on investments in these technologies, while a new one will benefit its customers more. The fact that WinRT might not be applicable for many enterprise applications might hold true for a while, but as with Windows Phone — the main target of Windows 8 is not enterprise customers. Microsoft is trying to fight a battle for minds of consumers already learning to live with Apple&#8217;s and Google&#8217;s competing technologies — the fact that could cost Microsoft its dominance in OS in the future if not addressed with <em>something exciting and superior. I believe Windows 8 is such thing</em>. Enterprises are now used to switching the OS every two years and have mostly last done so with Windows 7, so it won&#8217;t harm Microsoft much if they wait till Windows 9 before getting ready and realizing WinRT is already a very valid platform for many scenarios and will surely improve to become a great one for developing business software too.</p>
<p><a name="appstore"></a></p>
<h2>The Store</h2>
<p><a href="http://www.flickr.com/photos/37567720@N05/7039000079/" title="Windows Store by Filip Skakun, on Flickr"><img src="http://farm8.staticflickr.com/7179/7039000079_cda85b56e8.jpg" width="500" height="313" alt="Windows Store"></a><br />&copy; Screenshot by <a href="http://twitter.com/xyzzer">Filip Skakun</a> 2012</p>
<p><em>A billion Windows users, even if only slowly upgrading to Windows 8, make Windows Store a very attractive platform for growing an app development business</em>. Most of the excitement and business opportunities for developers in recent years have been in web development with a switch to mobile development in recent years. Microsoft is far behind in this game, but I would not ignore the sleeping dragon. Windows will continue to be the most popular platform for desktops and laptops and Windows Store will fill a void finally enabling Windows developers to easily access the wallets of its gigantic user base. It will compete in the mobile space with established platforms from Apple and Google, but PC users have not had access to such a store until Windows 8. This is bound to breed a lot of innovation and rejuvenate the Windows ecosystem. Big development houses and brands like Adobe or Electronic Arts have achieved a level of familiarity and trustworthiness to be able to sell their software through their own online storefronts or could sell games through Steam, but Windows Store will allow millions of individual developers and small companies to share their ideas with hundreds of millions of users willing to pay for them or sell their attention to ad networks. I can easily see all future Windows games becoming available through the Windows Store. Is it the end of software on DVDs and GameStop? Not in the immediate future, since desktop applications will not be sold in the store except for perhaps one coming from the big software houses and it will take some years for most users to upgrade to Windows 8 and later versions of Windows, but especially for games — it is bound to happen soon. PC games are already increasingly being sold online through existing channels and another major one will surely accelerate this process.</p>
<p><a name="nextup"></a></p>
<h2>Next Up</h2>
<p>This was the first part of my impressions of Windows 8. The second part comes tomorrow and I will talk about the following:</p>
<ol>
<li>Windows 8 and the Cloud</li>
<li>Using Windows 8 on a Slate</li>
<li>Using Windows 8 on a Laptop</li>
<li>Using Windows 8 on a Desktop</li>
<li>Desktop IE vs. Metro IE</li>
<li>Frustrations of Being an Early Adopter</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/04/impressions-of-windows-8-part-1-of-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[GA2] Making a Game Out of Tower Defense (Part 2)</title>
		<link>http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/</link>
		<comments>http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 18:52:32 +0000</pubDate>
		<dc:creator>Mollie Harms</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1903</guid>
		<description><![CDATA[Finally, the long awaited Part 2 for Making a Game Out of Tower Defense.  Good thing too, considering we went gold at the end of last week!  Please grab the game here. A brief recap follows, in case you didn&#8217;t get to check out our first post located here.   Our team at Vectorform was tasked with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/full/" rel="attachment wp-att-1908"><img class="aligncenter size-full wp-image-1908" title="Galactic Alliance 2" src="http://labs.vectorform.com/wp-content/uploads/2012/03/full.png" alt="Galactic Alliance 2" width="560" height="420" /></a></p>
<p>Finally, the long awaited Part 2 for Making a Game Out of Tower Defense.  Good thing too, considering we went gold at the end of last week!  Please grab the game <a href="http://itunes.apple.com/us/app/galactic-alliance-2/id491354805?mt=8">here</a>.</p>
<p><span id="more-1903"></span></p>
<p>A brief recap follows, in case you didn&#8217;t get to check out our first post located <a href="http://labs.vectorform.com/2011/08/ga2-making-a-game-out-of-tower-defense/">here</a>.   Our team at Vectorform was tasked with revamping our chart-topping iPad game Galactic Alliance.  We were asked to create new enemies, new towers, new levels, and to round out the game with some of the more common features seen in other tower defense games.  Our first post discussed what tower defense is, the new towers seen in the game, and how the towers are introduced across our levels.  In this post I&#8217;d like to discuss our new enemies and some of the strategies involved in taking them down.</p>
<p>Galactic Alliance is an open map style of tower defense.  Players can place turrets wherever they would like on the grid and creeps (the bad guys) will travel the shortest path between their position and their goal.  The only rule is that you can&#8217;t completely block off the creeps&#8217; path.</p>
<p>Many tower defense games have the grunt (the standard enemy), the fast ones, the tanks, and flyers (enemies that don&#8217;t have to follow the path you laid out for them).  Galactic Alliance 2 has all of those and a few other creative mechanics that our enemies execute as well.</p>
<p><a href="http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/flyers/" rel="attachment wp-att-1905"><img class="aligncenter size-full wp-image-1905" title="Flying Creeps GA2" src="http://labs.vectorform.com/wp-content/uploads/2012/03/flyers.png" alt="Flying Creeps GA2" width="566" height="352" /></a></p>
<p>Flyers can really throw a wrench in the game, especially when they b-line straight down the middle of the field and avoid half of your strongest towers.  However, once you know they&#8217;re coming, you can build your strongest towers where you need and destroy them every time.  In order to keep players guessing we&#8217;ve introduced creeps that &#8220;phase&#8221; through space.  They are still bound to your path, but will periodically disappear and re-appear further down the grid.  The goal of these were to encourage the player to leave some money for urgent tower building, and to build a flexible path instead of, for example, building all their heaviest hitters around a single booster tower.</p>
<p>Galactic Alliance 2, like its predecessor, is a four player cooperative game.  We wanted to take advantage of that unique characteristic by introducing an enemy which would be periodically immune to each player.  These are lovingly referred to as &#8220;camo creeps&#8221; and will cycle through the four player colors as they travel down the map.  In this way, camo creeps are very similar to phasers in a single player game, but playing with friends makes them next to no trouble.  (Play with friends!  It&#8217;s a lot of fun!)</p>
<p><a href="http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/camo/" rel="attachment wp-att-1904"><img class="aligncenter" title="Camo Creeps" src="http://labs.vectorform.com/wp-content/uploads/2012/03/camo.png" alt="Camo Creeps" width="565" height="343" /></a></p>
<p>The phasing and camo creeps are two unique types that we&#8217;ve introduced.  We&#8217;ve also riffed on some of our previous types, pushing the bounds of what is considered &#8220;an upgrade&#8221;.  In many tower defense games, an upgrade entails a new piece of artwork on an enemy that has more health and moves faster.  Our enemies are already constantly gaining health through-out the game, so this mechanic didn&#8217;t seem to serve much of a purpose other than to introduce new artwork.  We did something slightly different with the upgrades instead.</p>
<p>GA2 explores the variety of groups of enemies more than its predecessor.  Each enemy has a faster version as well as a version that is often seen in tight packs.  While these variations maintain the same base characteristic as the core creep, they challenge the most tried and true strategies.  One of the most prominent examples is the super fast scouts, those guys are brutal.  They aren&#8217;t a typical upgrade because they have much less health than other scouts, but if you aren&#8217;t watching the game these scouts will punch through your defenses quickly.  Keep an eye open for these new varieties of enemies!</p>
<p>Hopefully you enjoyed our overview on creeps, the new types we&#8217;ve introduced and some of the strategies to take them out.  Please comment with any questions, thoughts, or encouragements, they are always appreciated.</p>
<p>Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/03/ga2-making-a-game-out-of-tower-defense-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous UI development in WinRT, Silverlight, Windows Phone &amp; WPF with async/await keywords of C# 5.0</title>
		<link>http://labs.vectorform.com/2012/02/asynchronous-ui-development-in-winrt-silverlight-windows-phone-wpf-with-asyncawait-keywords-of-c-5-0/</link>
		<comments>http://labs.vectorform.com/2012/02/asynchronous-ui-development-in-winrt-silverlight-windows-phone-wpf-with-asyncawait-keywords-of-c-5-0/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 17:13:42 +0000</pubDate>
		<dc:creator>Filip Skakun</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[async/await]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Web Forms]]></category>
		<category><![CDATA[Windows 8]]></category>
		<category><![CDATA[Windows Forms]]></category>
		<category><![CDATA[WinRT]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1705</guid>
		<description><![CDATA[C# 5.0 comes with the new async/await keywords that make asynchronous code easier to write, read and maintain. This is very nice if you have properly declared methods that support this pattern and Windows Runtime (or WinRT &#8211; the API for Windows 8 Metro Style Apps) comes with a lot of these methods for long [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/2012/02/asynchronous-ui-development-in-winrt-silverlight-windows-phone-wpf-with-asyncawait-keywords-of-c-5-0/helloasyncawait-2/" rel="attachment wp-att-1722"><img class="size-full wp-image-1722 aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2012/02/HelloAsyncAwait1.png" alt="" width="482" height="418" /></a></p>
<p>C# 5.0 comes with the new <strong>async/await</strong> keywords that make asynchronous code easier to write, read and maintain. This is very nice if you have properly declared methods that support this pattern and Windows Runtime (or WinRT &#8211; the API for Windows 8 Metro Style Apps) comes with a lot of these methods for long running tasks or ones of nondeterministic duration &#8211; especially in I/O or web calls. It is however completely lacking in support for asynchronous UI development, even though one of the main goals of these new keywords was support for responsive UI.</p>
<p>Interactive coding often introduces the need to start an operation, like an animation or a dialog box and then wait for an event before switching the state of the UI, for example: running another animation or removing a dialog. Reading this article you will learn how to do it better using the upcoming features of C# 5.0, regardless of whether you develop in WinRT, Silverlight, WPF, Windows Forms or even Web Forms. The source code that comes with this article contains a library you can use to cut the amount of code you need to write by half!</p>
<p><span id="more-1705"></span></p>
<p><strong>UI development of today and the past</strong></p>
<p>If you develop applications using .NET Framework  you probably have to deal with a lot of events, event handlers, event subscriptions, state machines, flag fields, helper types, etc. If you want to sequence a series of state transitions that depend on events you have no choice but to break up the logic of your code into separate methods and event handlers, subsequently your code quickly gets a bit ugly and hard to follow.</p>
<p>For example, if you want to run some code after an animation completes you would have to add an event handler to the &#8220;Completed&#8221; event first, then start the animation in one method and finally execute the rest of the code from the event handler a bit like here:</p>
<pre class="brush: csharp; title: ; notranslate">
public void RunAnimationThenDoSomething()
{
    storyboard.Begin();
}

private void storyboard_Completed(object sender, object e)
{
    DoSomething();
}
</pre>
<p>It seems fairly straightforward unless you have to remove the event handlers or have five other similar actions in a sequence &#8211; timer delays, waiting for button clicks, conditional blocks etc.</p>
<p>You can keep the code a bit more compact if you use lambda expressions, reactive extensions or iterator blocks, but they also make it more complicated. How about wrapping all the plumbing in #region blocks and collapsing them to leave only the logic visible in sequence? That would kind of work, but no. <img src='http://labs.vectorform.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>In come async and await keywords&#8230;</strong></p>
<p>How about getting rid of half of the event handlers, event subscriptions etc.? Let&#8217;s take a look at what you can do today if you develop for WinRT/Windows 8 or if you install the Async CTP or what you will be able to do in the near future.</p>
<p>WinRT does not help you much in terms of support awaitables in the UI classes, although you can wait for web requests, basic dialogs or just use Task.Delay() to delay execution:</p>
<pre class="brush: csharp; title: ; notranslate">
await new HttpClient().GetAsync(uri);
await new MessageDialog(&quot;Done!&quot;).ShowAsync();
await Task.Delay(1000);
</pre>
<p>How about a single method call to wait for your UI to load, one to wait for a second, one to run and wait for a storyboard to complete, one to wait for a button click and even check which button was clicked?</p>
<pre class="brush: csharp; title: ; notranslate">
public async void InteractWithUser()
{
    await this.WaitForLoaded();
    await showMessageStoryboard.BeginAsync();
    await Task.Delay(1000);
    await hideMessageStoryboard.BeginAsync();
    var button = await buttons.WaitForClickAsync();
    if (button == OKButton)
        Disk.Format(&quot;C:&quot;);
    else
        InteractWithUser();
}
</pre>
<p>The concept isn&#8217;t new &#8211; it seems like <a href="https://twitter.com/#!/Rickenhacker">Daniel Earwicker</a> in his <a href="http://smellegantcode.wordpress.com/2010/10/30/c-5-0-asyncawait-and-gui-events/">C# 5.0 async/await and GUI events</a> article mentioned having a &#8220;button as a task&#8221;. This here though is the implementation of the concept.</p>
<p><strong>Awaitable extension methods</strong></p>
<p>To add the new functionality to existing classes I am using extension methods. To make them awaitable, I am creating a task from a TaskCompletionSource that completes when the expected event occurs. I created a helper class based on <a href="https://twitter.com/#!/nitoprograms">Stephen Cleary&#8217;s</a> <a href="http://social.msdn.microsoft.com/Forums/sk/async/thread/30f3339c-5e04-4aa8-9a09-9be72d9d9a1b">post</a> on MSDN forums, but modified to work with WinRT. Here are the extensions and helper code I came up with:</p>
<p><pre class="brush: csharp; title: ; notranslate">
public static class StoryboardExtensions
{
    /// &lt;summary&gt;
    /// Begins a storyboard and waits for it to complete.
    /// &lt;/summary&gt;
    public static async Task BeginAsync(this Storyboard storyboard)
    {
        await EventAsync.FromEvent(
            eh =&gt; storyboard.Completed += eh,
            eh =&gt; storyboard.Completed -= eh,
            storyboard.Begin);
    }
}

public static class ButtonExtensions
{
    /// &lt;summary&gt;
    /// Waits for the button Click event.
    /// &lt;/summary&gt;
    public static async Task&lt;RoutedEventArgs&gt; WaitForClickAsync(this ButtonBase button)
    {
        return await EventAsync.FromRoutedEvent(
            eh =&gt; button.Click += eh,
            eh =&gt; button.Click -= eh);
    }
}

// Based on: http://social.msdn.microsoft.com/Forums/sk/async/thread/30f3339c-5e04-4aa8-9a09-9be72d9d9a1b
public static class EventAsync
{
    /// &lt;summary&gt;
    /// Creates a &lt;see cref=&quot;System.Threading.Tasks.Task&quot;/&gt;
    /// that waits for an event to occur.
    /// &lt;/summary&gt;
    /// &lt;example&gt;
    /// &lt;![CDATA[
    /// await EventAsync.FromEvent(
    ///     eh =&gt; storyboard.Completed += eh,
    ///     eh =&gt; storyboard.Completed -= eh,
    ///     storyboard.Begin);
    /// ]]&gt;
    /// &lt;/example&gt;
    /// &lt;param name=&quot;addEventHandler&quot;&gt;
    /// The action that subscribes to the event.
    /// &lt;/param&gt;
    /// &lt;param name=&quot;removeEventHandler&quot;&gt;
    /// The action that unsubscribes from the event when it first occurs.
    /// &lt;/param&gt;
    /// &lt;param name=&quot;beginAction&quot;&gt;
    /// The action to call after subscribing to the event.
    /// &lt;/param&gt;
    /// &lt;returns&gt;
    /// The &lt;see cref=&quot;System.Threading.Tasks.Task&quot;/&gt; that
    /// completes when the event registered in
    /// &lt;paramref name=&quot;addEventHandler&quot;/&gt; occurs.
    /// &lt;/returns&gt;
    public static Task&lt;object&gt; FromEvent(
        Action&lt;EventHandler&gt; addEventHandler,
        Action&lt;EventHandler&gt; removeEventHandler,
        Action beginAction = null)
    {
        return new EventHandlerTaskSource(
            addEventHandler,
            removeEventHandler,
            beginAction).Task;
    }

    /// &lt;summary&gt;
    /// Creates a &lt;see cref=&quot;System.Threading.Tasks.Task&quot;/&gt;
    /// that waits for an event to occur.
    /// &lt;/summary&gt;
    /// &lt;example&gt;
    /// &lt;![CDATA[
    /// await EventAsync.FromEvent(
    ///     eh =&gt; button.Click += eh,
    ///     eh =&gt; button.Click -= eh);
    /// ]]&gt;
    /// &lt;/example&gt;
    /// &lt;param name=&quot;addEventHandler&quot;&gt;
    /// The action that subscribes to the event.
    /// &lt;/param&gt;
    /// &lt;param name=&quot;removeEventHandler&quot;&gt;
    /// The action that unsubscribes from the event when it first occurs.
    /// &lt;/param&gt;
    /// &lt;param name=&quot;beginAction&quot;&gt;
    /// The action to call after subscribing to the event.
    /// &lt;/param&gt;
    /// &lt;returns&gt;
    /// The &lt;see cref=&quot;System.Threading.Tasks.Task&quot;/&gt; that
    /// completes when the event registered in
    /// &lt;paramref name=&quot;addEventHandler&quot;/&gt; occurs.
    /// &lt;/returns&gt;
    public static Task&lt;RoutedEventArgs&gt; FromRoutedEvent(
        Action&lt;RoutedEventHandler&gt; addEventHandler,
        Action&lt;RoutedEventHandler&gt; removeEventHandler,
        Action beginAction = null)
    {
        return new RoutedEventHandlerTaskSource(
            addEventHandler,
            removeEventHandler,
            beginAction).Task;
    }

    private sealed class EventHandlerTaskSource
    {
        private readonly TaskCompletionSource&lt;object&gt; tcs;
        private readonly Action&lt;EventHandler&gt; removeEventHandler;

        public EventHandlerTaskSource(
            Action&lt;EventHandler&gt; addEventHandler,
            Action&lt;EventHandler&gt; removeEventHandler,
            Action beginAction = null)
        {
            if (addEventHandler == null)
            {
                throw new ArgumentNullException(&quot;addEventHandler&quot;);
            }

            if (removeEventHandler == null)
            {
                throw new ArgumentNullException(&quot;removeEventHandler&quot;);
            }

            this.tcs = new TaskCompletionSource&lt;object&gt;();
            this.removeEventHandler = removeEventHandler;
            addEventHandler.Invoke(EventCompleted);

            if (beginAction != null)
            {
                beginAction.Invoke();
            }
        }

        /// &lt;summary&gt;
        /// Returns a task that waits for the event to occur.
        /// &lt;/summary&gt;
        public Task&lt;object&gt; Task
        {
            get { return tcs.Task; }
        }

        private void EventCompleted(object sender, object args)
        {
            this.removeEventHandler.Invoke(EventCompleted);
            this.tcs.SetResult(args);
        }
    }

    private sealed class RoutedEventHandlerTaskSource
    {
        private readonly TaskCompletionSource&lt;RoutedEventArgs&gt; tcs;
        private readonly Action&lt;RoutedEventHandler&gt; removeEventHandler;

        public RoutedEventHandlerTaskSource(
            Action&lt;RoutedEventHandler&gt; addEventHandler,
            Action&lt;RoutedEventHandler&gt; removeEventHandler,
            Action beginAction = null)
        {
            if (addEventHandler == null)
            {
                throw new ArgumentNullException(&quot;addEventHandler&quot;);
            }

            if (removeEventHandler == null)
            {
                throw new ArgumentNullException(&quot;removeEventHandler&quot;);
            }

            this.tcs = new TaskCompletionSource&lt;RoutedEventArgs&gt;();
            this.removeEventHandler = removeEventHandler;
            addEventHandler.Invoke(EventCompleted);

            if (beginAction != null)
            {
                beginAction.Invoke();
            }
        }

        /// &lt;summary&gt;
        /// Returns a task that waits for the routed to occur.
        /// &lt;/summary&gt;
        public Task&lt;RoutedEventArgs&gt; Task
        {
            get { return tcs.Task; }
        }

        private void EventCompleted(object sender, RoutedEventArgs args)
        {
            this.removeEventHandler.Invoke(EventCompleted);
            this.tcs.SetResult(args);
        }
    }
}
</pre>
</p>
<p><strong>How do I use it today?</strong></p>
<p>The source code is available on <a href="http://asyncui.codeplex.com/SourceControl/list/changesets">CodePlex</a>. It comes with a library that works on Windows 8 Developer Preview and a sample project that has a custom dialog class for WinRT implemented, both using the classic event driven approach as well as using the extension methods for comparison. It also has versions of the library and samples for Silverlight 4.0, Windows Phone 7.1 (Mango) and WPF &#8211; all of which require Visual Studio 2010 with <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=9983">Async CTP 3</a> installed.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/02/asynchronous-ui-development-in-winrt-silverlight-windows-phone-wpf-with-asyncawait-keywords-of-c-5-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thoughts from CES: Day -1</title>
		<link>http://labs.vectorform.com/2012/01/thoughts-from-ces-day-1/</link>
		<comments>http://labs.vectorform.com/2012/01/thoughts-from-ces-day-1/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 19:32:15 +0000</pubDate>
		<dc:creator>Joe Engalan</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[2012 CES]]></category>
		<category><![CDATA[CES]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1665</guid>
		<description><![CDATA[  I arrived early to CES to help support our experiences. With that, I got an exhibitors pass which gave me pre-show access.   It only took a few hours to update things and make sure everything was setup. So, I had some time to kill. I thought I could get some exercise in by [...]]]></description>
			<content:encoded><![CDATA[<div dir="ltr">
<div><a href="http://labs.vectorform.com/wp-content/uploads/2012/01/CES.jpg" rel="lightbox[1665]"><img class="aligncenter size-full wp-image-1668" title="CES" src="http://labs.vectorform.com/wp-content/uploads/2012/01/CES.jpg" alt="" width="540" height="509" /></a></div>
<div> </div>
<div>I arrived early to CES to help support our experiences. With that, I got an exhibitors pass which gave me pre-show access.</div>
<div> </div>
<div>It only took a few hours to update things and make sure everything was setup. So, I had some time to kill. I thought I could get some exercise in by taking a walk through the hall, It was a lot of exercise. The Las Vegas Convention Center is huge and going through all 3 halls was a trek. Not to mention trying to avoid all of the construction cranes and crates.</div>
<div> </div>
<div>From my walk-about, I gleaned a few key nuggets. Not much detail yet, but I already know some of the big things.</div>
<div> <span id="more-1665"></span></div>
<div><strong>Android is big and it’s going to continue to grow.</strong></div>
<div>OEMs, large and small; expensive and cheap, are producing products running Android. iOS may be cool and chic, but any app developer not hitting Android is really missing out. For me, this means that we have to get our apps out on Android quicker and Microsoft will be in a good position to capture some of this market in the next few years. Microsoft should be in prime position to capture significant market share from those already *not* running iOS and want a cooler interface. Plus, if the promise of Windows 8 comes true, your personal PC and all it’s power goes with you cloud or not. Ice Cream Sandwich (Android 4.0), is cool and all but it’s still Android. If you don’t control the experience from top to bottom, you run the risk of someone putting your cool OS inside an underpowered chassis which creates a very poor brand experience.</div>
<div> </div>
<div><strong>Samsung Galaxy Note!</strong></div>
<div>Is it a tab? Is it a phone? Not really sure, but it’s all over central hall and I want one. I’m currently running a Galaxy Tab 7.0 Plus. While it’s cool and fits nicely in that zone between tablet and phone, it’s still not a one-handed device. Galaxy Note, with it’s 5.3″ screen is a one-handed device and I’m gonna jump on that.</div>
<div> </div>
<div><strong>Microsoft’s booth is all about Windows Phone and Kinect.</strong><br />They’re still putting a lot of stuff out so I couldn’t get any more details. I’ll check back tommorrow.</div>
<div> </div>
<div><strong>TVs TVs TVs.</strong><br />There are TVs all over the place. Smart TVs, 3D TVs, Thin TVs, Super-szied TVs. Of course, some (if not most) of the Smart TVs are running Android from what I could tell. More details I’m sure will emerge during the show. What this means to me is that all of the IPTV experiences we’ve been talking about are looking more and more real. A Smart TV running some kind of ARM processor can do a lot. A lot more than just streaming video.</div>
<div> </div>
<div><strong>Playoffs.</strong><br />It seemed like every single TV in the place was showing the Pittsburgh/Denver game and there were always a gaggle of people taking a break to watch. It’s like going to Best Buy in a large warehouse. Kind of amusing really.</div>
<div> </div>
<div>So that’s Day -1. There’s a lot more stuff still going up. This is just stuff I glanced at from walking around the construction. I can&#8217;t wait to walk the floor when it’s all ready.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2012/01/thoughts-from-ces-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tron: Illustrated</title>
		<link>http://labs.vectorform.com/2011/11/tron-illustrated/</link>
		<comments>http://labs.vectorform.com/2011/11/tron-illustrated/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 20:22:28 +0000</pubDate>
		<dc:creator>John Einselen</dc:creator>
				<category><![CDATA[Visuals]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[effects]]></category>
		<category><![CDATA[Lightwave]]></category>
		<category><![CDATA[Surface]]></category>
		<category><![CDATA[texture]]></category>
		<category><![CDATA[Tron]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1581</guid>
		<description><![CDATA[At Vectorform we get to work on a lot of high profile brands, and Disney’s Tron: Legacy HTML5 online graphic novel experience was no exception! Given a tight deadline, we created an interactive graphic novel that leveraged animations, effects, and audio made possible by the latest HTML5 technology. Such a cool experience needed a unique [...]]]></description>
			<content:encoded><![CDATA[<p>At Vectorform we get to work on a lot of high profile brands, and Disney’s <a href="http://disneydigitalbooks.go.com/tron/">Tron: Legacy HTML5</a> online graphic novel experience was no exception! Given a tight deadline, we created an interactive graphic novel that leveraged animations, effects, and audio made possible by the latest HTML5 technology.</p>
<p>Such a cool experience needed a unique intro screen and loading animation, something that was a bit more specialised than just a simple bar. Working on two rotating pieces that would lock together at 100%, I knew the style would need to remain consistent with the established look of the graphic novel, ink strokes and all. Instead of trying to illustrate each animation frame by hand, I turned to Lightwave.</p>
<p style="text-align: center;"><a class="an7_thumb_center" href="http://labs.vectorform.com/wp-content/uploads/2011/11/website.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/website1.jpg" alt="" width="480" height="120" /></a></p>
<p><span id="more-1581"></span></p>
<p>When developing shaders, be they photoreal or painterly, it’s always helpful to break the desired look down into easily replicable components. Using the cover illustration of the Tron graphic novel as a guide, we can see layers of base painting (smooth gradations), highlight brushing (smudgier daubs), and ink strokes (shading lines that follow the curves of the object).</p>
<p style="text-align: center;"><img class="an7_img_center aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/render-1.png" alt="" width="480" height="480" /></p>
<p>The base object is a simple donut shape with strong backlighting. Specialised surface development will almost always require a specific lighting setup to work well, and this is no exception. The style is of course flexible enough to be adapted elsewhere, but for tight control over the results we need to keep the lighting unchanged.</p>
<h2>Ink strokes</h2>
<p><a class="an7_thumb_left" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-1.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignleft" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-11.jpg" alt="" width="70" height="70" /></a><a class="an7_thumb_left" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-2.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignleft" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-21.jpg" alt="" width="70" height="70" /></a>At first glance this seems a little odd to try and replicate in 3D, but it’s easier than you might think. Using the crust procedural texture, we’ll stretch out the X and Y to give long strokes against the side of the object, then connect a Lambert shading node to the spot size input to control the thickness of the strokes.</p>
<p><a class="an7_thumb_right" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-3.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignright" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-31.jpg" alt="" width="70" height="70" /></a>With the addition of incidence and gradient nodes, we’ll adjust some of the shading subtleties, especially around the edges of objects where we want more of an outline. In simple cases like this, using an incidence gradient to outline an object can give smoother and more reliable results than Lightwave’s line renderer, plus allows us to add a thin white edge between the outline and the shading to help add a bit more definition. In more organic or complex models an incidence stroke is quite variable, which can either be good or bad depending on the desired style.</p>
<p style="text-align: center;"><img class="an7_img_center aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/render-3.png" alt="" width="480" height="480" /></p>
<p>This works great for such a circular shape, but if an object is more organic or has lines that are harder to follow with a procedural texture, you’ll want to explore more options, including variations on the type of procedural, direction, or even other mapping setups. Cross-hatched techniques were demoed a few years ago on the <a href="http://forums.newtek.com/showthread.php?t=89592">Newtek Ligthwave forums</a> by William Vaughan, and I’ve used variations on other projects as well. It’s surprising how well some pen and ink styles can be adapted to a Lightwave surface style using basic node setups.</p>
<h2>Base coloration</h2>
<p><a class="an7_thumb_left" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-4.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignleft" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-41.jpg" alt="" width="70" height="70" /></a><a class="an7_thumb_left" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-5.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignleft" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-51.jpg" alt="" width="70" height="70" /></a>Hues rarely remain constant through gradations of shading and light; not in real life, not in photography, not in illustrations, and, I hope, not in our 3D renders! We’ll take the same Lambert diffuse shading node used for the ink strokes, and add a gradient to create the base coloration. From deeper purple-blues to bright cyans, the hue shifts create life and depth in the surface. Mixing the Lambert diffuse shading with Phong specularity helps make the lighting falloff feel more metallic. Plus, what better way to pay homage to Tron than with an historic shading method? Always warms my heart to find unique ways of mixing in stuff like that.</p>
<p><a class="an7_thumb_right" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-6.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignright" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-61.jpg" alt="" width="70" height="70" /></a><a class="an7_thumb_right" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-7.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignright" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-71.jpg" alt="" width="70" height="70" /></a>The colours work well enough, but it doesn’t feel particularly painterly without more surface variation. With cross-hatched crust nodes, we’ll use Denis Pontonnier’s <a href="http://dpont.pagesperso-orange.fr/plugins/nodes/Additionnal_Nodes_2.html">DPkit</a> Bump Normal node to convert the resulting bump values into normals that can be plugged into the Lambert and Phong shaders. Directly controlling normals like this is a great way to mix varied effects in the same surface, without being limited to a single global bump.</p>
<p style="text-align: center;"><img class="an7_img_center aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/render-5.png" alt="" width="480" height="480" /></p>
<h2>Highlight painting</h2>
<p><a class="an7_thumb_left" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-8.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignleft" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-81.jpg" alt="" width="70" height="70" /></a>Just about complete, the only thing left to add is the highlights. Using multiple Phong shaders allows us to mix both painterly and shiny surface properties easily. Using the cross hatched crust nodes already set up for the diffuse normals, we’ll modulate the shininess of the second one to give more brush stroke style shapes. Rather like a two-coat surface process, but with more organic results.</p>
<p style="text-align: center;"><img class="an7_img_center aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/render-6.png" alt="" width="480" height="480" /></p>
<p><a class="an7_thumb_right" href="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-9.jpg" rel="lightbox[1581]" rel="lightbox[id382]"><img class="alignright" src="http://labs.vectorform.com/wp-content/uploads/2011/11/screen-91.jpg" alt="" width="70" height="70" /></a>With the combination of normals, procedural stroke widths, and highlight modulations, the surface can react much like an illustration, but the patterns are essentially attached to the surface and completely stable during animation.</p>
<p>You can visit the <a href="http://disneydigitalbooks.go.com/tron/">Tron HTML5 website</a> to see the loading animation in action!</p>
<p style="text-align: center;"><img class="an7_img_center aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/11/render-final.png" alt="" width="480" height="480" /></p>
<h2>Download</h2>
<p>The .zip file contains the final sample scene, object, and an exported surface file for easy addition to a presets collection. There are a fair number of nodes that weren’t described in detail, so reviewing the setup by playing around with the pieces is the best way to really tear things apart. Enjoy!</p>
<p><a class="an7_button" title="Download Files" href="http://labs.vectorform.com/wp-content/uploads/2011/11/tronillustrated.zip">Download Files: final Lightwave assets</a></p>
<p>This surface requires the Bump Normal node found in Denis Pontonnier’s excellent (and free!) <a href="http://dpont.pagesperso-orange.fr/plugins/nodes/Additionnal_Nodes_2.html">DPkit</a>.</p>
<p class="small">Disney <em>and</em> Tron <em>are either registered trademarks or trademarks of Disney in the United States and/or other countries.</em></p>
<p class="small">Newtek <em>and</em> Lightwave 3D <em>are either registered trademarks or trademarks of Newtek Incorporated in the United States and/or other countries.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2011/11/tron-illustrated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Side-scrolling Game with UDK</title>
		<link>http://labs.vectorform.com/2011/11/creating-a-side-scrolling-game-with-udk/</link>
		<comments>http://labs.vectorform.com/2011/11/creating-a-side-scrolling-game-with-udk/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 14:15:53 +0000</pubDate>
		<dc:creator>Vasiliy Deych</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[platformer]]></category>
		<category><![CDATA[sidescroller]]></category>
		<category><![CDATA[udk]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1298</guid>
		<description><![CDATA[I wanted to find a way to introduce others to UDK in a way that is fun and simple. I discovered some notes I took while prototyping a simple UDK side-scroller, and turned them into this little guide. This guide attempts to lay out the groundwork for developing a simple game with the Unreal Development [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/10/image001.png" rel="lightbox[1298]"><img class="aligncenter size-full wp-image-1564" src="http://labs.vectorform.com/wp-content/uploads/2011/10/image001.png" alt="Creating a Side-scrolling Game with UDK" width="460" height="288" /></a></p>
<p>I wanted to find a way to introduce others to UDK in a way that is fun and simple. I discovered some notes I took while prototyping a simple UDK side-scroller, and turned them into this little guide. This guide attempts to lay out the groundwork for developing a simple game with the Unreal Development Kit. It will help readers understand the structure of a basic UDK game, its elements and the relationship between them. It does not, however, detail creating levels or assets. For that, please refer to the excellent <a href="http://udn.epicgames.com/Three/VideoTutorials.html#3D Buzz Video Tutorials - Using UDK" target="_blank">3D Buzz video tutorials available on the UDK website</a>.</p>
<p><span id="more-1298"></span></p>
<p><strong><em>Update:</em></strong><br /><em>The complete source code and level file created during this guide is available here: <a href="http://labs.vectorform.com/files/Tomato.zip">http://labs.vectorform.com/files/Tomato.zip</a></em>
<ul style="background-color: #e0e0e0;border: 1px solid #CCCCCC;padding: 10px">
<li><strong>Introduction to the UDK environment</strong>
<ul>
<li><a href="#UDK, Unreal Script and Unreal Ed">UDK, Unreal Script and Unreal Ed</a></li>
<li><a href="#Getting UDK">Getting UDK</a></li>
<li><a href="#The Directory Structure">The Directory Structure</a></li>
<li><a href="#The Code Base">The Code Base</a></li>
</ul>
</li>
<li><strong>Creating a Side-scroller</strong>
<ul>
<li><a href="#Creating a New Game Type">Creating a New Game Type</a></li>
<li><a href="#Creating 2D Player Controls">Creating 2D Player Controls</a></li>
<li><a href="#Compiling Your Game">Compiling Your Game</a></li>
<li><a href="#Running Your Game">Creating A Level and Running The Game</a></li>
<li><a href="#Coin Pickups">Adding Coin Pickups</a></li>
<li><a href="#Adding a Coin Mesh">Adding a Coin Mesh and Making Coins Disappear When Collected</a></li>
<li><a href="#Creating Custom Actions">Creating Custom Actions</a></li>
<ul>
<li><a href="#Enabling Debug Output">Enabling Debug Output</a></li>
<li><a href="#Using Actions from Unreal Kismet">Using Actions from Unreal Kismet</a></li>
</ul>
<li><a href="#Creating a Custom HUD">Creating a Custom HUD</a></li>
<li><strong>Creating Bots</strong>
<ul>
<li><a href="#Creating Bot Behavior in UnrealScript">Creating Bot Behavior in UnrealScript</a></li>
<li><a href="#Adding and Configuring Bots in the Level">Configuring, and Adding Bots to the Level</a></li>
</ul>
</li>
<li><a href="#Game Over">Game Over!</a></li>
</ul>
</li>
</ul>
<p><a name="UDK, Unreal Script and Unreal Ed"></a></p>
<h2>UDK, Unreal Script and Unreal Ed</h2>
<p>Development with UDK consists of two parts:</p>
<ol>
<li>Writing Unreal Script code to create game objects and low-level game logic &#8212; such as AI, multiplayer behavior, game rules, and so on.</li>
<li>Using Unreal Ed to design the game visually, using the Unreal Script objects you wrote. Unreal Ed is a powerful tool for designing levels and UI, managing assets, adding level-specific logic (switches, portals), and much more.</li>
</ol>
<p>I highly recommend that you learn Unreal Ed before jumping into code &#8212; it will help you understand the terminology used throughout UDK. I recommend watching the 3DBuzz video tutorials on using the level editor and Kismet (a visual editor for high-level gameplay logic), which can be found here: <a href="http://udn.epicgames.com/Three/VideoTutorials.html">http://udn.epicgames.com/Three/VideoTutorials.html</a>. You will even learn to create a 3rd person game as you follow along!</p>
<p>UDK comes with the Unreal Engine codebase and the full source code for the Unreal Tournament 3 demo game. If you have experience with C++, C#, Objective C, Java or similar, I find that reading the codebase is the fastest way to learn Unreal Script.</p>
<p><a name="Getting UDK"></a></p>
<h2>Getting UDK</h2>
<p>Head over to <a title="http://www.udk.com/download" href="http://www.udk.com/download" target="_blank">http://www.udk.com/download</a> and grab the latest release. I have the September 2011 beta but yours may be newer. Install UDK.</p>
<p>Additionally, you will need the following:</p>
<ol>
<li><strong>A text editor.</strong> Unreal Script (.uc) source files can be edited with any text editor. I recommend ConTEXT with the UnrealScript language file, or <a title="jEdit" href="http://www.jedit.org/">jEdit</a> because you will get the benefit of syntax highlighting right out of the box.</li>
<li><strong>UnCodeX.</strong> It is a stand-alone project navigator for UDK source files &#8212; it scans all the Unreal Script files you have, and presents you with a well-organized class tree. You get a major benefit of having an IDE for free. Get it here: <a href="http://udn.epicgames.com/Three/UnCodeX.html">http://udn.epicgames.com/Three/UnCodeX.html</a> (make sure you carefully follow the instructions under the <strong>&#8220;Installation&#8221;</strong> heading)</li>
</ol>
<p>Third-party IDEs are also available for Unreal Script development, but will not be covered here.</p>
<p><a name="The Directory Structure"></a></p>
<h2>The Directory Structure</h2>
<p>Now that you have UDK installed, let’s look at the various files and directories that make up UDK. Open up the UDK install directory (usually something like C:/UDK/UDK-2011-09). The two directories that are important for us are Development and UDKGame:</p>
<p style="padding-left: 30px"><strong>[UDK install directory]/Development/Src</strong> contains the Unreal Script files that make up the UDK code base (more on this below).</p>
<p style="padding-left: 30px"><strong>[UDK install directory]/UDKGame</strong> contains the game’s levels, textures, meshes, sounds and scripts &#8212; all compiled into packages. Levels have a .udk extension, assets are .upk and the script packages are .u.</p>
<p>More details about the directory structure can be found on Epic&#8217;s Unreal Development Network website: <a href="http://udn.epicgames.com/Three/DevelopmentKitFirstScriptProject.html#UDK directory layout">http://udn.epicgames.com/Three/DevelopmentKitFirstScriptProject.html#UDK directory layout</a></p>
<p><a name="The Code Base"></a></p>
<h2>The Code Base</h2>
<p>This code base is a large and complex hierarchy of Unreal Script classes. Networking, vehicles, AI behavior, lights, UI elements &#8212; are just some of the examples of classes available to you. Each script in the code base (file with .uc extension) bears the name of the class it defines.  Each class derives from another class, and eventually from the base class <em>Object. </em>The scripts are organized into directories bearing the name of the package to which they belong (Engine, Core, UTGame, etc). A package is an assembly created when you compile your scripts.</p>
<p>It is important to note at this point that all objects in the game world are derived from the class <em>Actor. </em> <em>Actors</em> include light sources, players, weapons, rocks, switches, waypoints. <em>Actors</em> do not need to be visible. In a typical game, most of your development time will be spent on creating <em>Actor</em> classes.</p>
<p><a name="Creating a New Game Type"></a></p>
<h2>Creating a New Game Type</h2>
<h1> </h1>
<p>I will name the game Total Maximum Torque, or &#8220;Tomato&#8221; for short. Create the following directories for your source files:</p>
<div>
<ol>
<li>Create<span style="color: #008000"> [UDK install directory]/Development/Src/Tomato</span></li>
<li>Create <span style="color: #008000">[UDK install directory]/Development/Src/Tomato/Classes</span></li>
</ol>
</div>
<p>We will create a custom game type by defining our own <em>GameInfo</em> subclass.  <em>GameInfo</em> is just an <em>Actor</em> that is created once when we load a map, and handles the game rules (spawning players, time limits, scoring, etc). You might think of it as an entry point to your game, because it determines what other objects will be used in the game. <span style="color: #888888">How does UDK know which GameInfo class to load? We have to tell it either in the URL or in the game&#8217;s .ini file (more on all this later).</span></p>
<p>To save some work, we will reuse Unreal Tournament 3&#8242;s <em>GameInfo</em> class. It is called <em>UTGame</em>, and it eventually extends <em>GameInfo</em>. If the game were drastically different from UT, we would subclass <em>GameInfo</em> directly, but our game will use a lot of Unreal Tournament&#8217;s existing functionality. Create and open <span style="color: #008000">[UDK install directory]/Development/Src/Tomato/Classes/TomatoGameInfo.uc<span style="color: #000000">. Add the following code:</span></span></p>
<pre class="brush: java; title: ; notranslate">
class TomatoGameInfo extends UTGame;

DefaultProperties
{
	MapPrefixes(0)=&quot;TMT&quot;
	DefaultPawnClass=Class'Tomato.TomatoPawn'
	PlayerControllerClass=Class'Tomato.TomatoPlayerController'
	BotClass=class'Tomato.TomatoBot'
	HUDType=class'Tomato.TomatoHUD'

	bUseClassicHUD = true

	DefaultInventory(0)=none
	DefaultInventory(1)=none
}
</pre>
<p>First, we declared our class name, and the name of the class it&#8217;s extending.</p>
<p>The <em>DefaultProperties</em> block contains default/initial values for class properties. We are subclassing, and these class properties already exist &#8212; we are just changing their default values. Our game will have its own HUD, bot class, controls, and pawn class &#8212; in <em>GameInfo</em> we specify that we want to use our classes instead of the classes defined in <em>UTGame.</em></p>
<ul>
<li>• A <em>Pawn</em> is an actor that can be controlled by players or AI. Typically, it is some kind of a mesh that can collide with the world, pick up items, take damage, and use weapons.  We want to have our own pawn that can only move in two dimensions, so we tell our <em>GameInfo</em> to use it as the standard pawn class.</li>
<li>• The <em>PlayerController</em> provides a way for human players to control pawns. We want to define our own 2D controls, so we will have <em>GameInfo</em> use our class.</li>
<li>• The Bot class is similar to the <em>PlayerController</em> in that it controls pawns. However, bot use AI instead of player input.</li>
<li>• A custom HUD is needed to display our score</li>
</ul>
<p><a name="Creating 2D Player Controls"></a></p>
<h2>Creating 2D Player Controls</h2>
<p>We&#8217;re going to take a little shortcut. Epic provided us with excellent code for a side-scrolling camera on the UDN website.</p>
<p><a href="http://udn.epicgames.com/Three/CameraTechnicalGuide.html#Example Side-Scrolling Camera">http://udn.epicgames.com/Three/CameraTechnicalGuide.html#Example Side-Scrolling Camera</a></p>
<p>Go ahead and copy the side-scrolling camera code Epic provided, and put it into the respective files (<span style="color: #008000">UDNPawn.uc</span> and <span style="color: #008000">UDNPlayerController.uc</span> in the Tomato source directory).</p>
<p><em>UDNPawn</em> derives from <em>UTPawn</em>. It overrides <em>CalcCamera </em>to fix camera position to the plane Y=<em>CamOffsetDistance</em> (0 by default), and to restrict camera rotation to face in the direction of the positive Y-axis. It also overrides <em>GetBaseAimRotation to</em> restrict the direction of aiming. <em>UDNPlayerController </em>modifies the player controls to only rotate and move the player&#8217;s pawn within the 2D plane.</p>
<p>UDNPawn.uc:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class UDNPawn extends UTPawn;

var float CamOffsetDistance; //Position on Y-axis to lock camera to

//override to make player mesh visible by default
simulated event BecomeViewTarget( PlayerController PC )
{
   local UTPlayerController UTPC;

   Super.BecomeViewTarget(PC);

   if (LocalPlayer(PC.Player) != None)
   {
      UTPC = UTPlayerController(PC);
      if (UTPC != None)
      {
         //set player controller to behind view and make mesh visible
         UTPC.SetBehindView(true);
         SetMeshVisibility(UTPC.bBehindView);
         UTPC.bNoCrosshair = true;
      }
   }
}

simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
{
   out_CamLoc = Location;
   out_CamLoc.Y = CamOffsetDistance;

   out_CamRot.Pitch = 0;
   out_CamRot.Yaw = 16384;
   out_CamRot.Roll = 0;
   return true;
}

simulated singular event Rotator GetBaseAimRotation()
{
   local rotator   POVRot;

   POVRot = Rotation;
   if( (Rotation.Yaw % 65535 &gt; 16384 &amp;&amp; Rotation.Yaw % 65535 &lt; 49560) ||
      (Rotation.Yaw % 65535 &lt; -16384 &amp;&amp; Rotation.Yaw % 65535 &gt; -49560) )
   {
      POVRot.Yaw = 32768;
   }
   else
   {
      POVRot.Yaw = 0;
   }

   if( POVRot.Pitch == 0 )
   {
      POVRot.Pitch = RemoteViewPitch &lt;&lt; 8;
   }

   return POVRot;
}   

defaultproperties
{
   CamOffsetDistance=0.0
}
</pre>
<p>UDNPlayerController.uc:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class UDNPlayerController extends UTPlayerController;

state PlayerWalking
{
ignores SeePlayer, HearNoise, Bump;

   function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
   {
      local Rotator tempRot;

      if( Pawn == None )
      {
         return;
      }

      if (Role == ROLE_Authority)
      {
         // Update ViewPitch for remote clients
         Pawn.SetRemoteViewPitch( Rotation.Pitch );
      }

      Pawn.Acceleration.X = -1 * PlayerInput.aStrafe * DeltaTime * 100 * PlayerInput.MoveForwardSpeed;
      Pawn.Acceleration.Y = 0;
      Pawn.Acceleration.Z = 0;

      tempRot.Pitch = Pawn.Rotation.Pitch;
      tempRot.Roll = 0;
      if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) &gt; 0)
      {
         tempRot.Yaw = 0;
         Pawn.SetRotation(tempRot);
      }
      else if(Normal(Pawn.Acceleration) Dot Vect(1,0,0) &lt; 0)
      {
         tempRot.Yaw = 32768;
         Pawn.SetRotation(tempRot);
      }

      CheckJumpOrDuck();
   }
}

function UpdateRotation( float DeltaTime )
{
   local Rotator   DeltaRot, ViewRotation;

   ViewRotation = Rotation;

   // Calculate Delta to be applied on ViewRotation
   DeltaRot.Yaw = Pawn.Rotation.Yaw;
   DeltaRot.Pitch   = PlayerInput.aLookUp;

   ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot );
   SetRotation(ViewRotation);
}   

defaultproperties
{
}
</pre>
<p>We now have UDNPlayerController, UDNPawn and TomatoGameInfo classes. In <em>TomatoGameInfo</em> we specified that our player controller will be <em>TomatoPlayerController </em>and the pawn class will be <em>TomatoPawn</em>. Let&#8217;s create those classes, and base them on the UDN classes we created &#8212; this will later allow us to add our own functionality without becoming distracted by Epic&#8217;s sidescroller camera code.</p>
<p>Create the file <span style="color: #008000">TomatoPlayerController.uc</span> with the following code:</p>
<pre class="brush: java; title: ; notranslate">
class TomatoPlayerController extends UDNPlayerController
	dependson(UDNPlayerController);
</pre>
<p>Likewise, create <span style="color: #008000">TomatoPawn.uc</span> with the following:</p>
<pre class="brush: java; title: ; notranslate">
class TomatoPawn extends UDNPawn
	dependson(UDNPawn);

simulated function Tick(float DeltaTime)
{
        local vector tmpLocation;
	super.Tick(DeltaTime);
        tmpLocation = Location;
        tmpLocation.Y = 500;
        SetLocation(tmpLocation);
}

function bool Dodge(eDoubleClickDir DoubleClickMove)
{
  return false;
}

defaultproperties
{
 ControllerClass=class'Tomato.TomatoBot'
 bCanStrafe=false
 MaxStepHeight=50.0
 MaxJumpHeight=96
 JumpZ=550
}
</pre>
<p>In the code above, we are forcing any of our pawns in the game (players and bots) to be on the Y=500 plane. We are also increasing the jump and step heights to make terrain easier to navigate and more similar to a platformer.</p>
<p>Create <span style="color: #008000">TomatoBot.uc</span> with this code:</p>
<pre class="brush: java; title: ; notranslate">
class TomatoBot extends UTBot;
</pre>
<p>We will leave TomatoBot empty for now. We will create bot AI at a later time.</p>
<p>Create <span style="color: #008000">TomatoHUD.uc</span> with this code:</p>
<pre class="brush: java; title: ; notranslate">
class TomatoHUD extends UTHUD;
</pre>
<p>We&#8217;ve now added all the classes that <em>TomatoGameInfo</em> references. Let&#8217;s compile them!</p>
<p><a name="Compiling Your Game"></a></p>
<h2>Compiling Your Game</h2>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/10/CompileScripts2.png" rel="lightbox[1298]"><img class="alignright size-medium wp-image-1492" src="http://labs.vectorform.com/wp-content/uploads/2011/10/CompileScripts2-300x223.png" alt="" width="300" height="223" /></a>We must compile our UnrealScript classes into a package in order to use them in the game. UDK maintains a list of all packages that need to be compiled in an <em>.ini</em> file &#8212; so we must add our package to that list. Open <span style="color: #008000">[UDK install directory]/UDKGame/Config/DefaultEngine.ini</span>. In the section<em> [UnrealEd.EditorEngine]</em>, add the following line, and save the file:</p>
<pre>+ModEditPackages=Tomato</pre>
<p>Run the Unreal Frontend tool (<span style="color: #008000">[UDK install directory]/Binaries/UnrealFrontend.exe</span>). We will be using this tool to invoke the compiler. Ensure that all your Unreal Script files are saved, and close UDK Editor if it is open. Select <em>&#8220;Compile Scripts&#8221;</em> from the<em> &#8221;Scripts&#8221;</em> menu.</p>
<p>You should not receive any errors or warnings related to the Tomato scripts.</p>
<p>See the <a href="http://udn.epicgames.com/Three/DevelopmentKitFirstScriptProject.html#Compiling">Compiling section on the UDN website</a> if you need additional details.</p>
<p><a name="Running Your Game"></a></p>
<h2>Creating A Level and Running The Game</h2>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/dKGs-69jnoM?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><strong><em>Save your level as TMT-Zone1.udk</em></strong></p>
<h1>Adding Coin Pickups</h1>
<p>Now that we have movement and camera controls working, it&#8217;s time to give the player something to do. We will add some coins that can be collected. Once all coins are collected, the game is won.</p>
<p><a name="Adding a Coin Mesh"></a></p>
<h2>Adding a Coin Mesh and Making Coins Disappear When Collected</h2>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/3izvQ-xFU_4?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><strong><em>Save your level (File-&gt;Save All)</em></strong></p>
<div><span class="Apple-style-span" style="font-size: 20px;font-weight: bold">Creating Custom Actions</span></div>
<p>We need to add the ability to track the number of coins collected, and to set the total number of coins needed to win the level. This can all be done in Unreal Kismet, but we would have to re-create this logic for each level in our game. Additionally, it does not serve as a good demonstration of a flexible architecture for a complete game. I am going to show you how to create communication between your level and your Unreal Script code.</p>
<p>What should be the responsibilities of the level (or level designer) in our game?</p>
<ol>
<li>The level should tell our script how many coins the player needs to complete this level.</li>
<li>The level should notify our script when a player collected a coin.</li>
<li>The level should tell our script if a player earned points.</li>
</ol>
<p>In the previous section we used Unreal Kismet to call the Destroy action when a coin was touched. Essentially, we want to do the same thing, but instead of Destroy we want to create our own actions.  When the action is performed, we&#8217;d like to call some function in our Unreal Script. To accomplish this, we will use <em>SequenceAction</em>s.</p>
<p>Create a new Unreal Script file named<span style="color: #008000"> SeqAct_TMTCollectCoin.uc</span>  in our source directory. The code is very simple:</p>
<pre class="brush: java; title: ; notranslate">
class SeqAct_TMTCollectCoin extends SequenceAction;

DefaultProperties
 {
 	ObjName=&quot;Collect Coin&quot;
        ObjCategory=&quot;Tomato&quot;
 	HandlerName=&quot;CollectCoin&quot;
 }
</pre>
<p>We are creating an action with the readable name &#8220;Collect Coin&#8221; in the category &#8220;Tomato&#8221; (defining a category allows us to group together all &#8220;Tomato&#8221; actions in Kismet&#8217;s context menus). We are also defining the name of the handler function for this action.</p>
<p>Let&#8217;s create the rest of the actions first, and then move on to creating handlers for them. Create <span style="color: #008000">SeqAct_TMTSetCoinsNeeded.uc</span> with the following:</p>
<pre class="brush: java; title: ; notranslate">
class SeqAct_TMTSetCoinsNeeded extends SequenceAction;

var() int NumCoins;

DefaultProperties
 {
 	ObjName=&quot;Set Coins Needed&quot;
        ObjCategory=&quot;Tomato&quot;
 	HandlerName=&quot;SetCoinsNeeded&quot;
 	NumCoins = 0
 	VariableLinks(1)=(ExpectedType=class'SeqVar_Int', LinkDesc=&quot;NumCoins&quot;, bWriteable=true, PropertyName=NumCoins)
 }
</pre>
<p>The above-action is an action that takes a parameter. We first declare a local variable <em>NumCoins. </em>We then set a <em>VariableLink</em> for the <em>NumCoins</em> variable &#8212; this creates a writable node in Kismet to which an integer value can be attached. You will see how to pass values later.</p>
<p>Create <span style="color: #008000"> SeqAct_TMTGivePoints.uc</span> with the following code:</p>
<pre class="brush: java; title: ; notranslate">
class SeqAct_TMTGivePoints extends SequenceAction;

var() int NumPoints;
DefaultProperties
 {
 	ObjName=&quot;Add Points&quot;
        ObjCategory=&quot;Tomato&quot;
 	HandlerName=&quot;AddPoints&quot;
 	NumPoints = 0
 	VariableLinks(1)=(ExpectedType=class'SeqVar_Int', LinkDesc=&quot;NumPoints&quot;, bWriteable=true, PropertyName=NumPoints)
 }
</pre>
<p>The &#8220;Add Points&#8221; action also takes an integer parameter &#8212; we use it to specify the number of points to add.</p>
<p>Time to create handlers for our new actions. In <span style="color: #008000">TomatoPlayerController.uc</span>, modify the class definition in the beginning of the file to add three dependson directives for our actions. This will ensure that the actions are compiled before our player controller, so our player controller can use them. Modify <em>TomatoPlayerController</em> as follows:</p>
<pre class="brush: java; title: ; notranslate">
class TomatoPlayerController extends UDNPlayerController
	dependson(UDNPlayerController)
        dependson(SeqAct_TMTGivePoints)
        dependson(SeqAct_TMTSetCoinsNeeded)
        dependson(SeqAct_TMTCollectCoin);
</pre>
<p>Next, we want to keep track of the number of points, the number of coins collected and the required number of coins &#8212; so we need some local variables. Right below, declare the following three integer variables:</p>
<pre class="brush: java; first-line: 8; title: ; notranslate">
var() int TMTPoints;
var() int TMTCoinsCollected;
var() int TMTCoinsNeededThisLevel;
</pre>
<p>Before we jump into creating the handlers, let&#8217;s create a function to test if the player has enough coins to win the game:</p>
<pre class="brush: java; first-line: 12; title: ; notranslate">
exec function TestWinningConditions()
{
  `log(&quot;TestWinningConditions() : Checking winning conditions&quot;);
  `log(&quot;TestWinningConditions() : Collected: &quot;$TMTCoinsCollected);
  `log(&quot;TestWinningConditions() : Needed: &quot;$TMTCoinsNeededThisLevel);

  if(TMTCoinsCollected &gt; 0 &amp;&amp; TMTCoinsNeededThisLevel &gt; 0 &amp;&amp; TMTCoinsCollected &gt;= TMTCoinsNeededThisLevel)
  {
       `log(&quot;TestWinningConditions() : Victory!&quot;);
  }
  else
  {
       `log(&quot;TestWinningConditions() : Go collect more coins!&quot;);
  }
}
</pre>
<p>The above-code should be self-explanatory, with the exception of <em>exec function</em>. An <em>exec function</em> can be invoked by typing its name in the console. Executing the function directly from console will make debugging winning conditions a bit easier.</p>
<p>Time to create handlers. To create a handler for an action, we must declare a method named with the value of the action&#8217;s <em>HandlerName</em> property. Also, the method will take the action as a parameter. Create the following handler functions in TomatoPlayerController:</p>
<pre class="brush: java; first-line: 28; title: ; notranslate">
function CollectCoin(SeqAct_TMTCollectCoin MyAction)
{
  `log(&quot;CollectCoin() : Collected coin&quot;);
  TMTCoinsCollected += 1;
  TestWinningConditions();
}
function SetCoinsNeeded(SeqAct_TMTSetCoinsNeeded MyAction)
{
  `log(&quot;SetCoinsNeeded() : Set needed coins to &quot;$MyAction.NumCoins);
  TMTCoinsNeededThisLevel = MyAction.NumCoins;
}
function AddPoints(SeqAct_TMTGivePoints MyAction)
{
  `log(&quot;AddPoints() : Adding points: &quot;$MyAction.NumPoints);
  TMTPoints += MyAction.NumPoints;
}
</pre>
<p>Finally, let&#8217;s properly initialize our properties:</p>
<pre class="brush: java; first-line: 48; title: ; notranslate">
defaultproperties
{
  TMTPoints = 0
  TMTCoinsCollected = 0
  TMTCoinsNeededThisLevel = 1
}
</pre>
<p>Expand to see the complete TomatoPlayerController.uc file:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class TomatoPlayerController extends UDNPlayerController
	dependson(UDNPlayerController)
        dependson(SeqAct_TMTGivePoints)
        dependson(SeqAct_TMTSetCoinsNeeded)
        dependson(SeqAct_TMTCollectCoin);

var() int TMTPoints;
var() int TMTCoinsCollected;
var() int TMTCoinsNeededThisLevel;

exec function TestWinningConditions()
{
  `log(&quot;TestWinningConditions() : Checking winning conditions&quot;);
  `log(&quot;TestWinningConditions() : Collected: &quot;$TMTCoinsCollected);
  `log(&quot;TestWinningConditions() : Needed: &quot;$TMTCoinsNeededThisLevel);

  if(TMTCoinsCollected &gt; 0 &amp;&amp; TMTCoinsNeededThisLevel &gt; 0 &amp;&amp; TMTCoinsCollected &gt;= TMTCoinsNeededThisLevel)
  {
       `log(&quot;TestWinningConditions() : Victory!&quot;);
  }
  else
  {
       `log(&quot;TestWinningConditions() : Go collect more coins!&quot;);
  }
}

function CollectCoin(SeqAct_TMTCollectCoin MyAction)
{
  `log(&quot;CollectCoin(): Collected coin&quot;);
  self.TMTCoinsCollected += 1;
  TestWinningConditions();
}
function SetCoinsNeeded(SeqAct_TMTSetCoinsNeeded MyAction)
{
  `log(&quot;SetCoinsNeeded() : Set needed coins to &quot;$MyAction.NumCoins);
  TMTCoinsNeededThisLevel = MyAction.NumCoins;

}
function AddPoints(SeqAct_TMTGivePoints MyAction)
{
  `log(&quot;AddPoints() : Adding points: &quot;$MyAction.NumPoints);

  TMTPoints += MyAction.NumPoints;

}

defaultproperties
{
  TMTPoints = 0
  TMTCoinsCollected = 0
  TMTCoinsNeededThisLevel = 1
}
</pre>
<p>How does the engine know to call the handlers for each action in the Player Controller class, and not in some other class? We will later need to specify, in Kismet, that the <em>Target</em> of the action is the Player Controller &#8212; just like we set the coin as a target of the Destroy action.</p>
<p>Things seem to finally be coming together. Ensure that UDK Editor is closed, save all files, and compile the scripts using Unreal Frontend (select<em> Script-&gt;Compile scripts</em>).</p>
<p><a name="Enabling Debug Output"></a></p>
<h2>Enabling Debug Output</h2>
<p>Before we fire up UDK, we need to enable the debug console. This will allow us to see the <em>`log()</em> output. The idea is to add a &#8220;-log&#8221; command-line parameter when launching the UDK editor. I set it up this way:</p>
<ol>
<li>Right-click UDKLift.exe (it&#8217;s in C:\UDK\UDK-2011-09\Binaries) and choose &#8220;Create shortcut&#8221;.</li>
<li>In the Properties of the short-cut, modify the &#8220;Target&#8221; as follows:
<pre>C:\UDK\UDK-2011-09\Binaries\UDKLift.exe editor -log</pre>
</li>
</ol>
<p>You can now use this shortcut to launch the UDK editor with a debug log window.</p>
<p><a name="Using Actions from Unreal Kismet"></a></p>
<h2>Using Actions from Unreal Kismet</h2>
<p>Once all scripts have compiled successfully, run UDK Editor with the debug log window enabled. Open up the level we worked on previously, <em>TMT-Zone1.udk</em>.</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/6OEzDsBYfPA?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>Take your time and design a level to your liking (if you haven&#8217;t already done so). Have a look at the 3D Buzz video tutorials for information on the various level design features available in UDK &#8212; things like destructible objects, switches, doors and terrain can be a great addition to your game! And add some more coins while you&#8217;re at it.</p>
<h1>Creating a Custom HUD</h1>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/10/CompletedHUD.png" rel="lightbox[1298]"><img class="alignnone size-medium wp-image-1448" src="http://labs.vectorform.com/wp-content/uploads/2011/10/CompletedHUD-300x215.png" alt="" width="300" height="215" /></a></p>
<p>We will be creating a very basic HUD. Modify <span style="color: #008000">TomatoHUD.uc</span> as follows:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class TomatoHUD extends UTHUD;

function DrawHealthBar(float percentFull)
 {
 	local int currentBarWidth;
 	local int maxBarWidth;
 	local int barHeight;
 	local int barPositionX;
 	local int barPositionY;
 	local int healthPct;

 	maxBarWidth = 300;
 	barHeight = 20;
 	barPositionX = 20;
 	barPositionY = 20;
 	healthPct = percentFull * 100;

 	currentBarWidth = maxBarWidth * percentFull;

        // Draw the &quot;filled&quot; part of the bar
 	Canvas.SetPos(barPositionX, barPositionY);        // X, Y position
 	Canvas.SetDrawColor(80, 200, 80, 200);    // R, G, B, A for bar rectangle
 	Canvas.DrawRect(currentBarWidth, barHeight);

        // Draw the empty part of the bar
 	Canvas.SetPos(barPositionX + currentBarWidth, barPositionY);
 	Canvas.SetDrawColor(200, 255, 200, 110);
 	Canvas.DrawRect(maxBarWidth - currentBarWidth, barHeight);

        // Draw some text next to the bar
	Canvas.SetPos(barPositionX + maxBarWidth + 10, barPositionY);
 	Canvas.SetDrawColor(0, 200, 0, 200);
 	Canvas.Font = class'Engine'.static.GetMediumFont();
 	Canvas.DrawText(&quot;Health: &quot;$healthPct$&quot;%&quot;);
 }

 function DrawString(string text, int X, int Y, int R, int G, int B, int A)
 {
        Canvas.SetPos(X, Y);
 	Canvas.SetDrawColor(R, G, B, A);
 	Canvas.Font = class'Engine'.static.GetMediumFont();
 	Canvas.DrawText(text);
 }

 function DrawGameHud()
 {
 	local TomatoPlayerController PC;

 	// Type cast the PlayerOwner property of the HUD to TomatoPlayerController
 	PC = TomatoPlayerController(PlayerOwner);

 	if (!PlayerOwner.IsDead())
 	{
           // Display health bar only when the player hasn't died
           if(PlayerOwner.Pawn.HealthMax &gt; 0)
           {
             DrawHealthBar(float(PlayerOwner.Pawn.Health) / float(PlayerOwner.Pawn.HealthMax));
           }
 	}

        // Always display other information
 	DrawString(&quot;Coins: &quot;$PC.TMTCoinsCollected$&quot;/&quot;$PC.TMTCoinsNeededThisLevel,20,40,140,80,0,200);
 	DrawString(&quot;Score: &quot;$PC.TMTPoints,20,60,0,80,160,200);
 }

 defaultproperties
 {
   bCrosshairShow=false
 }
</pre>
<p>For this basic HUD, we are using Canvas to draw text, and rectangles to represent our health bar. For a description of what each Canvas method does,  refer to <a href="http://udkc.info/index.php?title=Tutorials:Basic_HUD">this tutorial at UDK Central</a>. Ensure that UDK is closed, and compile your scripts. When you load and play TMT-Zone1.udk, you should have a fancy new HUD!</p>
<p>If you wish to create an advanced HUD, <a href="http://noexp.wordpress.com/scaleform-hud-tutorial/">refer to this complete series of video tutorials on using Scaleform GFx to create a HUD</a>.</p>
<h2>Creating Bots</h2>
<p><a name="Creating Bot Behavior in UnrealScript"></a></p>
<p><strong>Creating Bot Behavior in UnrealScript</strong></p>
<p>Bots are <em>Controllers</em> of Pawns, just like a Player Controller. We will modify the Unreal Tournament bots to make them better side-scroller opponents. The bots should begin attacking when they are very close to the player, since AI designed for 3D has a large sight radius. Additionally, they should patrol between two nodes (just like in the 3DBuzz video tutorials, but we will use Unreal Script instead of just Kismet to achieve this).</p>
<p>The way in which I designed the bots is probably not ideal, but it works and is really easy. Essentially, the bot will patrol between two nodes (these are just Actors). While that is happening, the bot will constantly check if the player is nearby and if there is a line of sight to the player. If there is, the bot will begin to attack until the target dies. I started creating this behavior by copy-pasting the Defending state from UTBot.uc, and modifying it. This is always a great starting point for learn the code base and creating your own behavior.</p>
<p>Since the bots require two path nodes, we need a way to tell the bot script what path nodes to use through Kismet. To achieve this, we will create a sequence action to configure our bot.</p>
<p>Create the file SeqAct_TMTConfigureBot.uc with the following code:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class SeqAct_TMTConfigureBot extends SequenceAction;

var() object Target;
var() float MaxFireRange;
var() object PatrolStart;
var() object PatrolEnd;

defaultproperties
{
  ObjName=&quot;Configure a TomatoBot&quot;
  ObjCategory=&quot;Tomato&quot;
  HandlerName = &quot;TMTConfigureBot&quot;

  target = None
  MaxFireRange = 256
  PatrolStart = None
  PatrolEnd = None

  VariableLinks(1)=(ExpectedType=class'SeqVar_Object', LinkDesc=&quot;Firing Target&quot;, bWriteable=true, PropertyName=Target)
  VariableLinks(2)=(ExpectedType=class'SeqVar_Float', LinkDesc=&quot;Max. Fire Range&quot;, bWriteable=true, PropertyName=MaxFireRange)
  VariableLinks(3)=(ExpectedType=class'SeqVar_Object', LinkDesc=&quot;Patrol Start&quot;, bWriteable=true, PropertyName=PatrolStart)
  VariableLinks(4)=(ExpectedType=class'SeqVar_Object', LinkDesc=&quot;Patrol End&quot;, bWriteable=true, PropertyName=PatrolEnd)
}
</pre>
<p>The Target variable link is the target that the bot will attack (this will be the player). MaxFireRange is how close to the player the bot needs to be to start attacking. PatrolStart and PatrolEnd are the patrol path nodes, the bot will walk between them.</p>
<p>Open the file TomatoBot.uc and edit it as follows:</p>
<pre class="brush: java; collapse: true; light: false; title: ; toolbar: true; notranslate">
class TomatoBot extends UTBot;

var() actor TMTPatrolStart;
var() actor TMTPatrolEnd;
var() actor TMTTarget;
var() float TMTMaxFireRange;

function TMTConfigureBot(SeqAct_TMTConfigureBot MyAction)
{
  TMTPatrolStart = actor(MyAction.PatrolStart);
  TMTPatrolEnd = actor(MyAction.PatrolEnd);
  TMTTarget = actor(MyAction.Target);
  TMTMaxFireRange = MyAction.MaxFireRange;
  SetTimer(0.3, true, 'ScanForPlayers');
}

function bool ShouldStrafeTo(Actor WayPoint)
{
	return false;
}

function ScanForPlayers()
{
	if(TMTTarget != none &amp;&amp; VSize(Controller(TMTTarget).Pawn.Location - Pawn.Location) &lt; TMTMaxFireRange &amp;&amp; FastTrace(Controller(TMTTarget).Pawn.Location, Pawn.Location,, true))
	{
		Focus = TMTTarget;
		Enemy = Controller(TMTTarget).Pawn;

		VisibleEnemy = Enemy;
		EnemyVisibilityTime = WorldInfo.TimeSeconds;
		bEnemyIsVisible = true;

		`log(&quot;TomatoBot::ScanForPlayers() : I see the player!&quot;);

                if(!IsInState('ChargingNoStrafe'))
                {
		 `log(&quot;TomatoBot::ScanForPlayers() : Going to CharginNoStrafe state&quot;);
                 GotoState('ChargingNoStrafe');
                }
	}
}

state Defending
{
	ignores EnemyNotVisible;

	function Restart( bool bVehicleTransition ) {}

	function bool IsDefending()
	{
		return true;
	}

	function EnableBumps()
	{
		enable('NotifyBump');
	}

	event MonitoredPawnAlert()
	{
		WhatToDoNext();
	}

	function ClearPathFor(Controller C)
	{
	}

	function SetRouteGoal()
	{
		local Actor NextMoveTarget;
		local bool bCanDetour;

		bCanDetour = (Vehicle(Pawn) == None) || (UTVehicle_Hoverboard(Pawn) != None);

		if ( ActorReachable(RouteGoal) )
			NextMovetarget = RouteGoal;
		else
			NextMoveTarget = FindPathToward(RouteGoal, bCanDetour);

		if ( NextMoveTarget == None )
		{
			NextMoveTarget = FindPathToward(RouteGoal, bCanDetour);
		}

		if ( NextMoveTarget == None )
		{
			CampTime = 3;
			// No target
			GotoState('Defending','Pausing');
		}

		Focus = NextMoveTarget;
		MoveTarget = NextMoveTarget;
	}

	function EndState(Name NextStateName)
	{
		MonitoredPawn = None;
		SetCombatTimer();
		bShortCamp = false;
	}

	function BeginState(Name PreviousStateName) { }
Begin:

	`log(&quot;BEGIN DEFENDING&quot;);

	WaitForLanding();
	CampTime = bShortCamp ? 0.3 : 3.0;
	bShortCamp = false;

	SetRouteGoal();

	if (Pawn.ReachedDestination(RouteGoal) )
	{
		Goto('Pausing');
	}
	else
	{
Moving:

		`log(&quot;MOVE DEFENDING&quot;);

		Pawn.bWantsToCrouch = false;

		MoveToward(MoveTarget, MoveTarget, 20, false, true);

		if (Pawn.ReachedDestination(RouteGoal))
		{
			goto('Pausing');
		}
	}
	LatentWhatToDoNext();

Pausing:
	`log(&quot;PAUSE DEFENDING&quot;);

	StopMovement();

	Pawn.bWantsToCrouch = IsSniping() &amp;&amp; !WorldInfo.bUseConsoleInput;

	SetFocalPoint( Pawn.Location + vector(MoveTarget.Rotation) * 10.0 );

	SwitchToBestWeapon();

	Sleep(0.5);

	if (UTWeapon(Pawn.Weapon) != None &amp;&amp; UTWeapon(Pawn.Weapon).ShouldFireWithoutTarget())
		Pawn.BotFire(false);

	Sleep(FMax(0.1,CampTime - 0.5));

	// Paused at one destination, select the other destination
	if(RouteGoal != none &amp;&amp; RouteGoal == TMTPatrolEnd)
	{
		RouteGoal = TMTPatrolStart;
	}
	else
	{
		RouteGoal = TMTPatrolEnd;
	}

	LatentWhatToDoNext();
}

state ChargingNoStrafe extends Charging
{
	function bool StrafeFromDamage(float Damage, class&lt;DamageType&gt; DamageType, bool bFindDest)
	{
        	return false;
	}

	function bool TryStrafe(vector sideDir)
	{
		return false;
	}
}

defaultproperties
{
  TMTMaxFireRange = 500
  TMTPatrolEnd = None
  TMTPatrolStart = None
  TMTTarget = None
}
</pre>
<p>When the bot is configured using our action, it begins calling <em>ScanForPlayers</em> on a timer, which checks if the <em>TMTTarget</em> (our player) is in close enough. If that&#8217;s the case, it enters the <em>ChargingNoStrafe</em> state, which is almost entirely defined in UTBot.uc. If it does not find anything, it will be in a Defending state, walking between two path nodes defined by <em>TMTPatrolStart</em> and <em>TMTPatrolEnd</em>.</p>
<p>Save both files and re-compile the scripts.</p>
<p><a name="Adding and Configuring Bots in the Level"></a><strong>Configuring, and Adding Bots to the Level</strong></p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/8ev9LKb3xZg?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><a name="Game Over"></a></p>
<h2>Game Over!</h2>
<p>The last element to add to our game will be a &#8220;game over&#8221; screen. Ideally, you would use Scaleform to create such UI screens, but it is beyond the scope of this guide. We will simply use Kismet to create a sequence of actions that display an existing Scaleform GFx movie. To begin this sequence, we will need an event. This event will be triggered by our TestWinningConditions() method when the game is won. To begin, <strong>create a new class file named SeqEvent_TMTGameWon.uc</strong> with the following code:</p>
<pre class="brush: java; title: ; notranslate">
class SeqEvent_TMTGameWon extends SequenceEvent;

event Activated(){
       `log(&quot;IN SeqEvent_TMTGameWon Activated()&quot;);
}

defaultproperties
{
	ObjName=&quot;Tomato Game Won&quot;
	ObjCategory=&quot;Tomato&quot;
        bPlayerOnly = false
}
</pre>
<p>Next, let&#8217;s modify <strong>TestWinningConditions() in TomatoPlayerController.uc</strong>, to activate this event. Update the method as follows:</p>
<pre class="brush: java; title: ; notranslate">
exec function TestWinningConditions()
{
   local int i;
   local Sequence GameSeq;
   local array&lt;SequenceObject&gt; AllSeqEvents;

  `log(&quot;TestWinningConditions() : Checking winning conditions&quot;);
  `log(&quot;TestWinningConditions() : Collected: &quot;$TMTCoinsCollected);
  `log(&quot;TestWinningConditions() : Needed: &quot;$TMTCoinsNeededThisLevel);

  if(TMTCoinsCollected &gt; 0 &amp;&amp; TMTCoinsNeededThisLevel &gt; 0 &amp;&amp; TMTCoinsCollected &gt;= TMTCoinsNeededThisLevel)
  {
       `log(&quot;TestWinningConditions() : Victory!&quot;);
       GameSeq = WorldInfo.GetGameSequence();

       if(GameSeq != None)
       {
               GameSeq.FindSeqObjectsByClass(class'SeqEvent_TMTGameWon', true, AllSeqEvents);
               for(i=0; i&lt;AllSeqEvents.Length; i++)
                       SeqEvent_TMTGameWon(AllSeqEvents[i]).CheckActivate(WorldInfo, None);
       }
  }
  else
  {
       `log(&quot;TestWinningConditions() : Go collect more coins!&quot;);
  }
}
</pre>
<p>In the code above, we are simply getting and activating all sequence events of type SeqEvent_TMTGameWon.</p>
<p><strong>Save and compile all scripts.</strong></p>
<p>Open up UDK, and load TMT-Zone1.udk.</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/Xt7kTX5OdTI?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>The complete source code and level file created during this guide is available here: <a href="http://labs.vectorform.com/files/Tomato.zip">http://labs.vectorform.com/files/Tomato.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2011/11/creating-a-side-scrolling-game-with-udk/feed/</wfw:commentRss>
		<slash:comments>80</slash:comments>
		</item>
		<item>
		<title>Remote Temperature Monitoring With the Arduino &amp; SM5100B</title>
		<link>http://labs.vectorform.com/2011/10/remote-temperature-monitoring-with-the-arduino-sm5100b/</link>
		<comments>http://labs.vectorform.com/2011/10/remote-temperature-monitoring-with-the-arduino-sm5100b/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 16:45:37 +0000</pubDate>
		<dc:creator>Matt Tilchen</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1170</guid>
		<description><![CDATA[The Problem In January of 2010 the hot water heating system of my family&#8217;s lake house failed with catastrophic consequences. Many of the copper pipes in the home froze and burst. By the time we found out about the problem the damage had been done, and done well. The basement had several inches of water [...]]]></description>
			<content:encoded><![CDATA[<h3>The Problem</h3>
<p>In January of 2010 the hot water heating system of my family&#8217;s lake house failed with catastrophic consequences. Many of the copper pipes in the home froze and burst. By the time we found out about the problem the damage had been done, and done well. The basement had several inches of water in it and we were also treated to beautiful ice sculptures such as this one, formed on our deck.</p>
<div id="attachment_1197" class="wp-caption aligncenter" style="width: 370px"><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/ice-e1317410102394.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1197 " src="http://labs.vectorform.com/wp-content/uploads/2011/09/ice-e1317410102394.jpg" alt="" width="360" height="480" /></a>
<p class="wp-caption-text">Is this the Hoth system?</p>
</div>
<p><span id="more-1170"></span></p>
<p>Needless to say, once the insurance work was complete and things were as good as new, I did not want to repeat this again the following winter or any thereafter. The problem is that the home is roughly an hour away from our primary residence. Driving out to the house every day to check the temperature is obviously out of the question. But because frozen pipes can occur in as as little as 24 hours after a heating system failure during frigidly cold Michigan winters, knowing the state of the heating system at all times is vitally important. And no heating system is 100% reliable, so without knowledge of the temperatures and state of the heating system in the home it was going to be hard to sleep at night during the looming winter months.Faced with this dilemma I decided it would be a great opportunity for an embedded systems project. The result is a little box which sends temperature data in the home to my phone via SMS messages. Links to information and resources concerning almost every part/library/service used in this project may be found at the end of the post. The project ended up being a rather good investment as you will see in the exciting conclusion.</p>
<h3>Design</h3>
<p>The goal of the project was to remotely acquire and deliver temperature data measured from points in the heating system and home with the following design objectives in mind (in order of importance)</p>
<ol>
<li><span style="direction: ltr">Reliability</span></li>
<li><span style="direction: ltr">Low cost of operation (month to month variable costs)</span></li>
<li><span style="direction: ltr">Ease of construction, time to build</span></li>
<li><span style="direction: ltr">Relatively low up front cost</span></li>
</ol>
<p><span style="direction: ltr">After considering some designs using a pc/linux-based solution using some parts I had lying around I ended up deciding to base the project on the Arduino. I felt this would most satisfy all the design objectives except perhaps #4. #1 (less moving parts), #2 (extremely low power consumption vs. the pentium 4 board I had lying around) #3 (designed for rapid prototyping with excellent libraries available to reduce the amount of code). Thus, I based the project on the Arduino Uno.</span></p>
<div id="attachment_1199" class="wp-caption alignleft" style="width: 198px"><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/09950-01_i_ma.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1199" src="http://labs.vectorform.com/wp-content/uploads/2011/09/09950-01_i_ma.jpg" alt="" width="188" height="188" /></a>
<p class="wp-caption-text">Arduino Uno</p>
</div>
<p>To sample the temperatures I chose to use some Dallas Semiconductor DS18B20 One-wire sensors. I chose this over a regular thermistor because I wanted to be able to add or remove extra temperature sensors without having to rewire the box internally. If I want to add another sensor with this system I can just daisy-chain it to the existing wiring. I also believe that these sensors are a bit more precise and accurate.<a href="http://labs.vectorform.com/wp-content/uploads/2011/09/Pinouts_ds18s20.gif" rel="lightbox[1170]"><img class="alignright size-full wp-image-1240" src="http://labs.vectorform.com/wp-content/uploads/2011/09/Pinouts_ds18s20.gif" alt="" width="85" height="224" /></a></p>
<p>For communication I considered using a full-time internet connection but this ended up being too expensive and my experiences with the provider in that area in terms of reliability made me abandon this option. Using cellular data seemed like the only other possibility. Because of the extremely low bandwidth requirements of the application I found that I could rely on just using SMS messages to send the temperature data to my phone. Although the SM5100B cellular modem I picked for the job supports a GPRS/TCP connection, it was certainly overkill for this project.</p>
<div id="attachment_1200" class="wp-caption alignleft" style="width: 198px"><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/09533-02_i_ma.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1200 " src="http://labs.vectorform.com/wp-content/uploads/2011/09/09533-02_i_ma.jpg" alt="" width="188" height="188" /></a>
<p class="wp-caption-text">SM5100B &amp; Evaluation Board</p>
</div>
<p>The idea for the unit was to send temperature data once every four hours, if there were no critically low temperatures. This let me know that the system was functional. If messages did not arrive on time then there was still time for the system to recover or for me to go out and fix any problems with it. In the event that the unit measured a critically low temperature a message would be sent immediately.</p>
<h3>AT&amp;T Pay as You Go</h3>
<p>To keep the monthly costs low I found a &#8220;pay as you go&#8221; plan from AT&amp;T that requires no up front contract and only costs $4.99/month for 200 text messages. This was enough for the messaging frequency of the project with some room left for testing and mistakes.</p>
<p>I ordered a new SIM card for the SM5100B on Amazon for a few dollars (3G sim card required for the service) and installed it into the card slot on the eval board. After signing up on the AT&amp;T website, providing the IEMI number and SIM card info, I was ready to test the SM5100B.</p>
<h3>Setting up the SM5100B</h3>
<p>The SM5100B requires some configuration to get it running on the network. I mounted it in the eval board, connected it to power, plugged in the USB port and connected it to my Mac. I used the built in <em>screen</em> command from the OS X terminal to connect to the SM5100B&#8217;s UART0. The default baud rate of the unit is 115200 so I invoked <em>screen</em> as follows:
<div class="codesnip-container" >screen /dev/tty.usbmodem###### 115200</div>
<p> (The #&#8217;s imply that the exact name of the device, once plugged into your computer, will vary). Type CTRL-A then CTRL-\ to exit. If you have a PC then you can just use a terminal emulation program like Hyper Terminal to achieve the same result.</p>
<p>Once connected, you will see some status messages as the SM5100B starts up. There will be a status message indicating that the booting is complete and at that point you can start typing in &#8220;AT&#8221; commands to set things up and experiment. The first thing I did was issue <strong>ATE1</strong> to turn on local echo. After that, I set up the module to work on the GSM band appropriate for the AT&amp;T network in North America <strong>AT+SBAND=7</strong>. I rebooted the unit and then ran <span style="font-family: monospace"><strong>AT+CMFG=1 </strong></span>to put the unit into the appropriate (text-based) SMS mode. I sent a few messages manually to verify things were working.</p>
<h3>Adding a Second &#8220;soft&#8221; Serial Port</h3>
<p>I wanted to be able to easily interact with SM5100B and get diagnostic information from the running system by plugging the unit into my computer. Because the Arduino only has one hardware UART I am using the NewSoftSerial library to add another &#8220;soft&#8221; UART by utilizing two of the Arduino&#8217;s digital I/O ports (pins 6-rx and 7-tx). This extra serial port is used to communicate with the SM5100B module on its UART0 while the regular hardware UART on the Arduino is used to hook up to an external terminal via its USB port.</p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/sm5100b.jpg" rel="lightbox[1170]"><img class="alignnone size-full wp-image-1203" src="http://labs.vectorform.com/wp-content/uploads/2011/09/sm5100b.jpg" alt="" width="640" height="480" /></a></p>
<p>In order to do this I needed to clear the RX, DTR, RTS, TX, and CTS jumpers on the eval board per the SM5100B documentation. I removed these with desoldering wick and then soldered two wires for UART0 onto the eval board. These wires connect to pins 6 and 7 on the Arduino.</p>
<p>The code for the project provides communication between the terminal on the hardware UART and the &#8220;soft&#8221; serial port connected to the SM5100B. The code also recognizes the CTRL-Z character from the terminal as a request to sample and print out the temperature sensor data for testing purposes.</p>
<h3>Finding an Antenna</h3>
<p>I found this antenna while looking around on Digi-Key&#8217;s site.</p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2070.jpg" rel="lightbox[1170]"><img class="alignnone size-full wp-image-1205" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2070.jpg" alt="" width="640" height="480" /></a></p>
<p>It provides 3dB gain, which is enough for this application. One nice thing about it is the inclusion of adhesive backing on one side of the antenna for mounting purposes. I ended up mounting the antenna on a large window after finding the best signal there. You can get the SM5100B&#8217;s current signal strength with the <strong>AT+CSQ=?</strong> command. I have not had any signal strength issues while using this antenna to date.</p>
<h3>Wiring &amp; Communicating With the Temperature Sensors</h3>
<p>This project makes use of the helpful Dallas Temperature Control and OneWire libraries for the purposes of communication with the temperature sensors on the one-wire bus. I wired the sensors using the &#8220;parasitic power&#8221; configuration to simplify things. The 4.7k pull-up resistor is not visible in the pictures because it is soldered into the 5v and Pin 3 wires right before exiting the project enclosure, covered by shrink tube.</p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/Schematic-dallas-18s20.gif" rel="lightbox[1170]"><img class="alignnone size-full wp-image-1206" src="http://labs.vectorform.com/wp-content/uploads/2011/09/Schematic-dallas-18s20.gif" alt="" width="475" height="211" /></a></p>
<p>In the source code you will find that I have hard coded the addresses of the sensors. I needed to know which sensor was which in order to identify the particular thing being measured. I found the addresses of the sensors by connecting them and then loading some of the example code that comes with the Dallas Temperature Control library.</p>
<p>I installed two sensors onto the bus. One to measure ambient temperature in the home and the other to measure the temperature of one of the pipes carrying hot water from the heating system&#8217;s boiler. The thermostat in the home is set to 55 degrees F and fluctuates very little. The temperature of the pipe can be anywhere from 190 to around 55 (ambient target for thermostat) as the heating system cycles.</p>
<p style="text-align: center"><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2054.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1208 aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2054.jpg" alt="" width="320" height="240" /></a><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2068.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1207 aligncenter" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2068.jpg" alt="" width="320" height="240" /></a></p>
<h3>Supplying Power</h3>
<p>To supply power to the Arduino and SM5100B I am using a plain old 9v wall wart. Keep in mind that the SM5100B has some substantial current requirements and it will not function properly unless these requirements are met. When the cellular radio is active the unit can use up to 2A (350mA average). Powering the unit from the usb port is not an option. The 9v supply connects to the Arduino and then power is distributed to the SM5100B from the 5v source on the Arduino using a barrel jack connector. I wanted to be able to disconnect the two components easily so I am taking advantage of the pre-existing connector on the SM5100B eval board.</p>
<h3>Providing a Home for the Arduino &amp; SM5100B</h3>
<p>The Arduino and SMB100B board are living comfortably in a spacious project box from Radio Shack. The box features a floor made from PCB board scrap that is raised about a quarter inch off the bottom of the box with risers. The Arduino mounts to the raised floor and two holes provide access to both the USB and power connectors. The wires for the temperature sensor bus run out the other side of the enclosure through a rubber grommet. The SM5100B board mounts to the lid of the box with industrial strength padded / double-sided tape. Had the unit been pre-drilled with mounting holes I would have used those. Finally, I am employing the coaxial connector that comes with the SM5100B to run the antenna connection through the lid. The tenants are currently complaining about the ugly USB port window, which is horribly cut. I didn&#8217;t have a Dremel tool yet so please do not point and laugh.</p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2057.jpg" rel="lightbox[1170]"><img class="alignnone size-full wp-image-1245" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2057.jpg" alt="" width="640" height="480" /></a></p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2051.jpg" rel="lightbox[1170]"><img class="alignleft size-full wp-image-1246" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2051.jpg" alt="" width="320" height="240" /></a><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2053.jpg" rel="lightbox[1170]"><img class="size-full wp-image-1247 alignnone" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2053.jpg" alt="" width="320" height="240" /></a></p>
<h3>The Code</h3>
<p>The logic of the main control loop is essentially:</p>
<pre>loop
        if temps have not been sampled recently (check configured period)
  		sample temp sensors

	if request was made for temps via main serial port
		print current temps to terminal

	check temperature values for alarm condition

	if alarm exists (one or more temps below threshold)
		if alarm message has not been sent
			send alarm message

	else if it is time to send a report (once every four hours)
		send a report message with current temps

	if an alarm message was previously sent but there is no longer an alarm (temps above threshold again)
		send an alarm cleared message

	send bytes to terminal from the SM5100B and vice-versa

end loop</pre>
<p>The interesting parts of the code that deal with sending the SMS messages and getting temperature data from the sensors are found in the sendSMS(), sampleTemps() and setup() functions.</p>
<p>Here is a complete listing of the source</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;OneWire.h&gt;
#include &lt;DallasTemperature.h&gt;
#include &lt;NewSoftSerial.h&gt;

/*
  Assumes the following of the SM5100B that is connected:

  - Baud rate is set to 9600, the default for the unit is 115200 (AT+IPR=9600)
  - North American band/frequencies GSM 850, PCS 1900 selected (AT+SBAND=7)
  - SMS Mode is 'Text' (AT+CMGF=1)
  - Local echo is on (ATE1)

  Before running this sketch, run the above commands and save the config to non-volatile memory with: AT&amp;W
*/

// Data wire is pin 3 on the Arduino
#define ONE_WIRE_BUS 3

// 9 bit precision corresponds to 0.5 degrees C resolution
#define TEMPERATURE_PRECISION 9

// The number to send reports to
#define SMS_NUMBER &quot;12485555555&quot;

// The period in milliseconds to wait in between reports. 4 hours = 1000 * 60 * 60 * 4
#define SMS_REPORT_INTERVAL 14400000

// The period in milliseconds in between samples of the temp sensors. If we sample continually the serial ports
// will not have enough time to relay characters without being choppy
#define TEMP_SAMPLE_INTERVAL 1000

// The period in milliseconds to wait after an alarm clears to send a report. This will ensure that
// we do not send reports over and over if a temperature is hovering around a threshold. 30 minutes = 1000 * 60 * 30
#define ALARM_CLEAR_REPORT_INTERVAL 1800000

// The low temperature thresholds for each sensor in degrees Fahrenheit
#define PIPE_THRESHOLD_F 50.0
#define AMBIENT_THRESHOLD_F 40.0

// The most recently measured temperatures in degrees Celcius
float pipeTemp;
float ambientTemp;

// Create a 1-Wire bus for the temp sensors to use
OneWire oneWire(ONE_WIRE_BUS);

// Use the DallasTemperature library to simplify working with the OneWire sensors
DallasTemperature sensors(&amp;oneWire);

// These device addresses were determined in advance by running some of the DallasTemperature library example code
DeviceAddress pipeSensor =    {0x28, 0xA7, 0x96, 0x8E, 0x02, 0x00, 0x00, 0x6F};
DeviceAddress ambientSensor = {0x28, 0xFE, 0x8F, 0x8E, 0x02, 0x00, 0x00, 0x58};

// Used to save the last point in time that a report was sent
unsigned long lastReportTime;

// Used to save the last point in time we took a temperature reading
unsigned long lastTempSampleTime;

// Create a &quot;soft&quot; serial port on pins 6(RX) and 7(TX)
NewSoftSerial modem(6,7);

// Keep track of if we have sent an SMS for a newly triggered alarm
boolean alarmSent = false;

// A flag used to determine if we should print the current temp to the terminal for inspection
boolean printTempsToTerminal = false;

char incoming_char = 0;

void printCurrentTemps(Print *p)
{
  p-&gt;print(&quot;Pipe Temp: &quot;);
  printTemp(pipeSensor, p);
  p-&gt;print(&quot; - &quot;);
  p-&gt;print(&quot;Ambient Temp: &quot;);
  printTemp(ambientSensor, p);
}

void printTemp(DeviceAddress deviceAddress, Print *p)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC != DEVICE_DISCONNECTED)
  {
    p-&gt;print(DallasTemperature::toFahrenheit(tempC), 1);
    p-&gt;print(&quot; F&quot;);
  }
  else p-&gt;print(&quot;?&quot;);
}

void printResolution(DeviceAddress sensor)
{
  Serial.print(sensors.getResolution(sensor), DEC);
  Serial.println(&quot;-bit&quot;);
}

void sendSMS(char *msg)
{
  modem.print(&quot;AT+CMGS=&quot;);
  modem.print(34, BYTE);
  modem.print(SMS_NUMBER);
  modem.println(34, BYTE);
  modem.print(msg);
  modem.print(&quot; &quot;);
  printCurrentTemps(&amp;modem);
  delay(500);                // Wait for &quot;&gt;&quot; prompt
  modem.print(0x1A, BYTE);   // CTRL-Z
}

void setup(void)
{
  // Start the serial ports
  Serial.begin(9600);
  modem.begin(9600);
  Serial.println(&quot;Starting SM5100B Communication...&quot;);

  lastReportTime = lastTempSampleTime = millis();

  // Start up the temperature sensors
  sensors.begin();

  // We should see our two 2 devices
  Serial.print(&quot;Found &quot;);
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(&quot; sensors&quot;);

  // Set the resolution to use for measurement
  sensors.setResolution(pipeSensor, TEMPERATURE_PRECISION);
  sensors.setResolution(ambientSensor, TEMPERATURE_PRECISION);

  // Show the resolution to make sure it is what we expected
  Serial.print(&quot;Pipe Sensor Resolution: &quot;);
  printResolution(pipeSensor);
  Serial.print(&quot;Ambient Sensor Resolution: &quot;);
  printResolution(ambientSensor); 

  sampleTemps();
  printCurrentTemps(&amp;Serial);
  Serial.println();
}

void sampleTemps(void)
{
  // Get the temperatures from both sensors
  sensors.requestTemperatures();

  pipeTemp = sensors.getTempC(pipeSensor);
  ambientTemp = sensors.getTempC(ambientSensor);
}

boolean checkForAlarm(void)
{
  return (ambientTemp == DEVICE_DISCONNECTED || pipeTemp == DEVICE_DISCONNECTED ||
          DallasTemperature::toFahrenheit(pipeTemp) &lt;= PIPE_THRESHOLD_F ||
          DallasTemperature::toFahrenheit(ambientTemp) &lt;= AMBIENT_THRESHOLD_F);
}

void loop(void)
{
  unsigned long newTime = millis();

  // Take a temperature sample if it is time
  if ((newTime - lastTempSampleTime) &gt; TEMP_SAMPLE_INTERVAL)
  {
    sampleTemps();
    lastTempSampleTime = newTime;
  } 

  if (printTempsToTerminal)
  {
    printCurrentTemps(&amp;Serial);
    Serial.println();
    printTempsToTerminal = false;
  }

  boolean alarmActive = checkForAlarm();

  // If we have an unsent alarm send a message
  if (alarmActive &amp;&amp; !alarmSent)
  {
    sendSMS(&quot;(Alarm)&quot;);
    alarmSent = true;
    lastReportTime = newTime;    // This will reset the report interval
  }

  // Or send a message if we have reached the report interval
  else if ((newTime - lastReportTime) &gt; SMS_REPORT_INTERVAL)
  {
    lastReportTime = newTime;
    sendSMS(&quot;(Report)&quot;);
  }

  // Reset the alarmSent flag if an alarm clears and the interval has passed
  if (!alarmActive &amp;&amp; alarmSent &amp;&amp;
     ((newTime - lastReportTime) &gt; ALARM_CLEAR_REPORT_INTERVAL))
  {
    alarmSent = false;
    lastReportTime = newTime;
    sendSMS(&quot;(Alarm Clear)&quot;);
  } 

  while (modem.available() &gt; 0)
  {
    // Take any incoming data from the SM5100B modem and send it to the terminal
    incoming_char = modem.read();
    Serial.print(incoming_char);
  }
  // Relay input from the terminal to the SM5100B modem
  while (Serial.available() &gt; 0)
  {
    // If the character is CTRL-Z then set a flag we will check later to print the current temps to the terminal
    incoming_char = Serial.read();
    if (incoming_char == 0x1A)
    {
      printTempsToTerminal = true;
    }
    else
    {
      modem.print(incoming_char);
    }
  }
}
</pre>
<p>
<h3>The Finished Product</h3>
<p>Here is the completed project, ready to install at the home.</p>
<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2067.jpg" rel="lightbox[1170]"><img class="alignnone size-full wp-image-1211" src="http://labs.vectorform.com/wp-content/uploads/2011/09/IMG_2067.jpg" alt="" width="360" height="480" /></a></p>
<h3>Did it Work?</h3>
<p>After some testing I installed the system in late November. A couple of weeks later I saw some status messages come in at one of the four hour intervals that showed an unusually high reading for the ambient temperature (around 70). I called my neighbor at the house and had him go over to investigate. He called me and said the boiler in the basement was shooting flames out of the bottom. Apparently, something had fallen into and blocked the chimney, forcing the boiler flame to backdraft. High temperature explained and disaster averted.</p>
<p>The aforementioned malfunction caused irreparable damage to the boiler (some 30 years old) so I had to invest in a new one. This made me feel like the utility of my project was basically moot because this new boiler would be so reliable that I wouldn&#8217;t need to monitor it. Interestingly enough, two days after the new boiler was installed I started getting alert messages. I called the company who installed it and requested they go out and look at it. Sure enough, it was not running. They made some adjustments and left with it running fine. A couple of days later I started getting alerts again. The call and service trip was repeated. Additional tweaks were made. This routine actually occurred two more times before the company who installed the boiler replaced a faulty igniter. After replacing the igniter the system ran flawlessly the rest of the winter. And the temperature data continued to show up every four hours on my phone without a hiccup.</p>
<p>The total project cost was about $175 plus some materials and tools I had to buy and took about a month of here-and-there free time to research, assemble, code and test. Additionally, there was the $4.99 a month to provide cellular service for the messaging during the cold months. Considering how it saved me from burning down the house and then again after investing in the new heating system, I think it was definitely worth it <img src='http://labs.vectorform.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Links / Resources</h3>
<h5>Arduino Related</h5>
<ul>
<li><a href="http://arduino.cc">Arduino</a></li>
<li><a href="http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library" target="_blank">Dallas Temperature Control Library</a></li>
<li><a href="http://www.pjrc.com/teensy/td_libs_OneWire.html" target="_blank">OneWire Library</a></li>
<li><a href="http://arduiniana.org/libraries/newsoftserial/" target="_blank">NewSoftSerial Library</a></li>
</ul>
<h5>Parts</h5>
<ul>
<li><a href="http://www.sparkfun.com/products/9950" target="_blank">Arduino Uno</a></li>
<li><a href="http://www.sparkfun.com/products/9427" target="_blank">SM5100B Eval Board</a></li>
<li><a href="http://www.sparkfun.com/products/9533" target="_blank">SM5100B Cell Module</a></li>
<li><a href="http://www.sparkfun.com/products/245" target="_blank">Dallas DS18B20 Sensor</a></li>
<li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=931-1037-ND" target="_blank">Coaxial adhesive backed antenna</a></li>
</ul>
<h5>Service</h5>
<ul>
<li><a href="http://www.att.com/GoPhone" target="_blank">AT&amp;T Pay As You Go</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2011/10/remote-temperature-monitoring-with-the-arduino-sm5100b/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The impact of Apple’s Siri release: From the former lead iPhone developer of Siri</title>
		<link>http://labs.vectorform.com/2011/10/the-impact-of-apple%e2%80%99s-siri-release-from-the-former-lead-iphone-developer-of-siri/</link>
		<comments>http://labs.vectorform.com/2011/10/the-impact-of-apple%e2%80%99s-siri-release-from-the-former-lead-iphone-developer-of-siri/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 17:08:19 +0000</pubDate>
		<dc:creator>Jon Pielak</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Siri]]></category>

		<guid isPermaLink="false">http://labs.vectorform.com/?p=1367</guid>
		<description><![CDATA[The Siri application released with the iPhone 4s has the potential to radically impact how we interact with technology. Ed Wrenbeck, former lead developer from Siri, talks through his history with the app… On March 24th, 2008 I first talked with my friend Darren about a new venture he was involved with which was simply [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.vectorform.com/wp-content/uploads/2011/10/siri_logo.jpg" rel="lightbox[1367]"><img class="aligncenter size-full wp-image-1376" src="http://labs.vectorform.com/wp-content/uploads/2011/10/siri_logo.jpg" alt="" width="600" height="200" /></a></p>
<p>The Siri application released with the iPhone 4s has the potential to radically impact how we interact with technology. Ed Wrenbeck, former lead developer from Siri, talks through his history with the app…</p>
<p><span id="more-1367"></span></p>
<p>On March 24th, 2008 I first talked with my friend Darren about a new venture he was involved with which was simply called &#8220;Stealth Company&#8221; at the time. (try <a href="http://stealth-company.com/">http://stealth-company.com</a>) This was four months before the iPhone app store would officially launch.</p>
<p>We left off at that point with the general thought that we&#8217;d like to work together, but we didn&#8217;t come back to the project again until mid July of 2008. I officially started working on the Siri application in early August 2008. I was the only iPhone/Objective-C developer on the team. The work I was doing with the native iPhone application was really treated as an R&amp;D exercise. The go to market strategy was based mostly on a web experience.</p>
<p>When the iPhone application started to come together, aggressively utilizing the full capabilities of the device, it quickly became apparent that Siri was meant to be a first class mobile experience that could take advantage of the power and features available to a native application. Siri never really left its web roots behind though. From the earliest days right up until the last version offered on the app store, the user interface has been almost entirely an HTML web view with native elements tightly integrated around it. Siri stretched to the very limit what was possible to do with an integrated web interface on a mobile device.</p>
<p>The Siri application was first shown publicly at D7, the &#8220;All Things D&#8221; conference in May 2009. (<a href="http://allthingsd.com/20111004/in-depth-with-siri-the-full-demo-from-the-d7-conference-plus-an-old-school-bonus/">http://allthingsd.com/20111004/in-depth-with-siri-the-full-demo-from-the-d7-conference-plus-an-old-school-bonus/</a>) It was the first time I really got the sense that I was involved with a product that would be used by millions of people.  Impressing a veteran technology writer such as Walt Mossberg is not an easy task.</p>
<p><strong>Voice Recognition – the first piece</strong><br />Today Siri is closely associated with the voice recognition capabilities from Nuance, but VLingo was the first voice recognition system used in the app. Nuance would not come into play until just a few months before the application went onto the app store in early 2010. The team was almost fanatical about getting the voice recognition just right, and we went through endless tests trying to tune these platforms to ultimately maximize the results.</p>
<p>Commercials for digital assistants always seem more natural than the reality, and there’s a reason. State of the art voice recognition systems will rarely, if at all, return results with 100% confidence in the translated string. You can expect a 60-70% return on average. Siri cannot change that limitation; however the team was able to find ways to enhance it.</p>
<p><strong><img class="size-medium wp-image-1379 alignnone" src="http://labs.vectorform.com/wp-content/uploads/2011/10/photo3-200x300.png" alt="" width="200" height="300" />    <img class="size-medium wp-image-1380 alignnone" src="http://labs.vectorform.com/wp-content/uploads/2011/10/photo2-200x300.png" alt="" width="200" height="300" /></strong></p>
<p><strong>Natural Language Processing – what Apple saw in Siri</strong><br />Often times reviews on iTunes would comment on how the Siri app seems to do a better job than the Nuance app or Dragon dictate. The iPhone application is just the portal to the brains of Siri running on a bunch of servers. There, it can take a sentence and dissect it naturally. An example might be &#8220;Book a table at Il Fornaio in Novi for 7PM&#8221; and it determines that &#8220;Il Fornaio&#8221; is likely the name of a place and &#8220;Novi&#8221; is likely a location. This is referred to as natural language processing, and it is incredibly difficult to get right.</p>
<p>Many users and technology pundits are wondering what’s different from other voice recognition apps on other platforms. Platforms such as Android and Windows Phone 7 offer their own voice interaction capabilities. Don&#8217;t forget, iOS offered its own voice control interface prior to the introduction of Siri on the 4S. But they are missing the point of Siri itself, which is about what happens after the voice command has been turned into text.</p>
<p>Tell another system to &#8220;Book a table at Il Fornaio at 7:00 with my mom;&#8221; the system can no doubt create a calendar entry at 7:00 and might even know who your mom is. It might even be possible for that device to figure out the closest Il Fornaio restaurant. What differentiates the NLP logic in Siri is that it will maintain context so you could say: &#8220;Also send her an email reminder.&#8221; Siri will understand &#8216;her&#8217; and compose the email accordingly.</p>
<p>This comprehension of context requires a great deal of logic and processing behind the scenes. The media commonly refers to this as “Artificial Intelligence” but in reality…</p>
<p><strong>It’s not really AI</strong><br />With Natural language processing in the mix it feels more human, like it understands you. This in itself adds to the mystique surrounding Artificial Intelligence. But real AI can’t fit on a phone in our world…yet.</p>
<p>Siri is basically a contextual, semantic, personalized search engine. We affectionately called it a &#8220;Do&#8221; engine. A search engine can evaluate text strings and look for matching results. A “Do” engine maintains awareness of the user, everything it knows about that user and processes strings in the context of the user.</p>
<p>One interesting part of Siri is its ability to utilize five or six translations of a voice command to determine what the user is trying to say. When trying to recognize the name of a restaurant such as &#8220;Il Fornaio&#8221; or a city named &#8220;Novi&#8221; the voice recognition engine will typically return several possible matches, as these are not simple words in the dictionary. The recognition engine might see these as lower confidence scores in a direct voice translation, but in the context of a user, his surroundings and behavior, they may change their rank.</p>
<p>Sometimes, Siri’s uncanny ability to understand the environment and the user even surprised me. One of my common test requests would be something like “Find a Tigers&#8217; game”. One time I happened to be in San Jose and, not thinking, tested Siri with this request and was delightfully pleased when it offered to help me get tickets to an upcoming game in San Francisco when the Tigers came to town in a couple of weeks.</p>
<p>That last item, behavior, is a biggie. It requires trust – which Siri got with Apple.</p>
<p><strong>Big Brother factor – why Siri needed Apple</strong><br />For Siri to be really effective, it has to learn a great deal about the user. If it knows where you work, where you live and what kind of places you like to go, it can really start to tailor itself as it becomes an expert on you individually. This requires a great deal of trust in the institution collecting this data. Siri didn’t have this, but Apple has earned their street cred.</p>
<p>Developers are realizing that they can deliver amazing experiences when they understand more about the user. However, users today are careful to not give away too much of that information. With Apple’s strong reputation behind it, there’s a massive potential for success here.</p>
<p><strong>The formula is there, the market is perfect.<br /></strong>At Vectorform, I’m dealing with all sorts of exploratory technology, things that are pushing boundaries even further than my work with Siri. We are constantly looking at the digital landscape, mapping out current innovations and how they impact future trends.</p>
<p>The release of Siri to the masses has massive shockwave potential in our book.</p>
<p><strong>What we’re looking for on the horizon:</strong></p>
<p><strong>An open SDK</strong> – Intelligence needs to come from many sources. Siri will need to mine collective input from as many data sources as possible in order to grow and stay relevant. Siri can’t be a marketing engine for select partners. True digital assistants have to put the user first, just as the user would do when making a decision on their own. There is enormous potential for Siri to integrate with data sources of many different types. Opening Siri up while ensuring the quality of the data will be a challenge for Apple. However, the recent success with the iOS and Mac App Stores has given Apple an effective way to influence its third part developers.</p>
<p><strong>A single voice</strong> – The original vision for Siri was a personal assistant available to you from any device, anywhere, at any time. Apple has pulled back on that vision a bit and made Siri an accessory to your iPhone. Siri needs to start growing again and become your advocate across all your digital platforms. Long term, Vectorform is interested in determining what kind of role Siri can play in a vehicle or… </p>
<p><img class="aligncenter" src="http://www.macstories.net/wp-content/uploads/2011/10/Screen-Shot-2011-10-04-at-10.13.26-PM.png" alt="" width="600" height="346" /></p>
<p><em>Ed Wrenbeck is an iOS Architect at Vectorform. In a previous life, he was the lead iPhone developer of Siri.  “While I do know the intimate details of the Siri Application, I have no inside knowledge of the new Siri released by Apple.&#8221;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.vectorform.com/2011/10/the-impact-of-apple%e2%80%99s-siri-release-from-the-former-lead-iphone-developer-of-siri/feed/</wfw:commentRss>
		<slash:comments>89</slash:comments>
		</item>
	</channel>
</rss>

