<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2062085109638480566</id><updated>2011-12-03T22:46:44.095+11:00</updated><category term='Microsoft Student Partners'/><category term='Microsoft'/><category term='SCALE'/><category term='LOLCODE'/><category term='HDR'/><category term='Optimisation'/><category term='imagine cup'/><category term='NextWar'/><category term='MSPTeam2011'/><category term='XNA'/><category term='SolSector Engine'/><category term='wp7dev'/><category term='C++'/><category term='Code'/><category term='Windows Phone 7'/><category term='game design'/><category term='Mulithreading'/><category term='Dev Vs Dev'/><category term='Clouds'/><category term='SatView'/><category term='Debugging Horrors'/><category term='Perlin Noise'/><category term='DevVsDev'/><category term='imaging cup game design'/><category term='Uni'/><category term='Direct3D10'/><title type='text'>Sc4Freak's Devblog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8942838523342154939</id><published>2011-03-27T15:48:00.000+11:00</published><updated>2011-03-27T15:48:23.489+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imagine cup'/><category scheme='http://www.blogger.com/atom/ns#' term='MSPTeam2011'/><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Student Partners'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='game design'/><category scheme='http://www.blogger.com/atom/ns#' term='imaging cup game design'/><title type='text'>A follow-on to "IC Game Design – A Key Tip for Success"</title><content type='html'>Michael Quandt&amp;nbsp;&lt;a href="http://mquandt.com/blog/2011/03/ic-game-design-a-key-tip-for-success/"&gt;posted a good tip&lt;/a&gt; about entering your WP7 app into Imagine Cup Game Design: basically, &lt;strong&gt;don't put your game in the Games Hub&lt;/strong&gt;! The emulator doesn't include the Games Hub, which means when your .xap file gets deployed to the emulator, your game won't be accessible.&lt;br /&gt;&lt;br /&gt;But how to actually fix this? Luckily, it's a simple change: in your project, find the WMAppManifest.xml file and change &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Genre="Apps.Games"&lt;/span&gt; to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Genre="Apps.Normal"&lt;/span&gt;. Now when you deploy your .xap to the emulator, it'll show up in the app list rather than the Games Hub.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8942838523342154939?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8942838523342154939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8942838523342154939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8942838523342154939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8942838523342154939'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/03/follow-on-to-ic-game-design-key-tip-for.html' title='A follow-on to &quot;IC Game Design – A Key Tip for Success&quot;'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1178801439011540796</id><published>2011-03-03T23:42:00.004+11:00</published><updated>2011-03-03T23:52:21.661+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MSPTeam2011'/><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Student Partners'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>High Quality Dithering for Windows Phone 7</title><content type='html'>In &lt;a href="http://adtsai.blogspot.com/2011/02/tip-of-day-32bpp-backbuffers-in-xna.html"&gt;my last post&lt;/a&gt; I showed how to use a 32bpp backbuffer to prevent banding in XNA games. But as it turns out, the WP7 hardware specifications only specify a 16-bit LCD at minimum - and that there are devices out there which only have a 16-bit LCD. (I've heard, but have not been able to confirm, that the Samsung devices suffer especially from this).&lt;br /&gt;&lt;br /&gt;In that case, if a device only has an LCD capable of 16bpp, setting a 32bpp backbuffer isn't going to help. Instead, you need to &lt;b&gt;dither&lt;/b&gt; your images, which will reduce the bit-depth to 16bpp but in a way which reduces visible banding.&lt;br /&gt;&lt;br /&gt;I stumbled across this blog post &lt;a href="http://nerdplusart.com//photoshop-action-for-windows-phone-7-dithering"&gt;"Photoshop Action for Windows Phone Dithering"&lt;/a&gt;, which provides a photoshop script to dither images. It gets the job done, but I noticed that it produces a fairly low-quality dither - the end result is very grainy to my eyes.&lt;br /&gt;&lt;br /&gt;A while back when I worked on &lt;a href="http://metropolitanmelbourne.com/"&gt;Metropolitan Melbourne&lt;/a&gt;, I wrote my own little tool to dither images because WM6.5 only supported 16-bit colour graphics and I couldn't find any other simple tools for high-quality dithering. My tool is called ReduceBitDepthCPP, and takes an input 24-bit/32-bit image in .png or .bmp format, and reduces it to 16-bit (R5G6B5) colour using the &lt;a href="http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering"&gt;Floyd-Steinberg&lt;/a&gt; algorithm. The Floyd-Steinberg algorithm eliminates banding while minimising quantisation error. Here's a comparison picture:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-QwkG4Y7iu24/TW-EYFfJ2uI/AAAAAAAAAGw/fp6Eszt-mz8/s1600/final.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://lh5.googleusercontent.com/-QwkG4Y7iu24/TW-EYFfJ2uI/AAAAAAAAAGw/fp6Eszt-mz8/s1600/final.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;As expected, the undithered gradient has extreme banding. The "Photoshop" image was produced by using &lt;a href="http://nerdplusart.com//photoshop-action-for-windows-phone-7-dithering"&gt;the script&lt;/a&gt; mentioned earlier. If you look closely, the Photoshop image does get rid of banding but also introduces a lot of noise - which makes the image very grainy.&lt;br /&gt;&lt;br /&gt;On the top right is the Floyd-Steinberg algorithm produced by my tool, ReduceBitDepthCPP. It also eliminates banding but does so in a way that doesn't introduce a lot of noise, and the end result looks very close to the original.&lt;br /&gt;&lt;br /&gt;You can download ReduceBitDepthCPP below, with source as well. It's free for any use, and the source code is distributed under the MIT license.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://microngamestudios.com/files/reducebitdepth/ReduceBitDepthCPP.zip"&gt;Download ReduceBitDepthCPP (125KB)&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://microngamestudios.com/files/reducebitdepth/ReduceBitDepthCPPSource.zip"&gt;Download ReduceBitDepthCPP Source files (22KB)&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Instructions&lt;/h2&gt;ReduceBitDepthCPP is a command-line tool, which makes it easier to integrate into your build. To use it:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Extract the files somewhere (eg. C:\Temp\ReduceBitDepth\)&lt;/li&gt;&lt;li&gt;Open up a command prompt by pressing [win]+[r] and typing in "cmd"&lt;/li&gt;&lt;li&gt;Navigate to the directory where you extracted the files&lt;/li&gt;&lt;li&gt;Run ReduceBitDepthCPP.exe using the following syntax:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ReduceBitDepthCPP.exe infile outfile&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;Sample:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ReduceBitDepthCPP.exe C:\Temp\meow_orig.png C:\Temp\meow_dithered.png&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you found this useful, don't forget to &lt;a href="http://www.twitter.com/Sc4Freak"&gt;follow me on Twitter&lt;/a&gt;, and check out some of the stuff &lt;a href="http://microngamestudios.com/"&gt;on my website&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1178801439011540796?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1178801439011540796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1178801439011540796' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1178801439011540796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1178801439011540796'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/03/high-quality-dithering-for-windows.html' title='High Quality Dithering for Windows Phone 7'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-QwkG4Y7iu24/TW-EYFfJ2uI/AAAAAAAAAGw/fp6Eszt-mz8/s72-c/final.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1141870436325581305</id><published>2011-02-23T18:44:00.005+11:00</published><updated>2011-02-23T18:57:52.441+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DevVsDev'/><category scheme='http://www.blogger.com/atom/ns#' term='MSPTeam2011'/><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Student Partners'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Tip of the Day: 32bpp BackBuffers in XNA</title><content type='html'>Here's a tip: by default, XNA uses a 16-bit R5G6B5 back buffer format. This causes horrific banding if you use lots of gradients in your game. You can fix this by manually telling XNA to use a 32-bit backbuffer format.&lt;br /&gt;&lt;br /&gt;In you Game class's constructor, add this line:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;graphics.PreparingDeviceSettings += PreparingDeviceSettingsEventHandler;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And somewhere in your Game class, add this method:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;void PreparingDeviceSettingsEventHandler(object sender, PreparingDeviceSettingsEventArgs e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var pp = e.GraphicsDeviceInformation.PresentationParameters;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pp.BackBufferFormat = SurfaceFormat.Color;&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The difference won't show up in the emulator. But on an actual device, it'll vastly increase your image quality by getting rid of a lot of your banding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1141870436325581305?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1141870436325581305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1141870436325581305' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1141870436325581305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1141870436325581305'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/02/tip-of-day-32bpp-backbuffers-in-xna.html' title='Tip of the Day: 32bpp BackBuffers in XNA'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-5837538421919614655</id><published>2011-02-16T18:29:00.003+11:00</published><updated>2011-02-16T18:36:33.163+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DevVsDev'/><category scheme='http://www.blogger.com/atom/ns#' term='SatView'/><category scheme='http://www.blogger.com/atom/ns#' term='MSPTeam2011'/><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Student Partners'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><title type='text'>SatView for Windows Phone 7 Released!</title><content type='html'>I'm happy to announce that SatView is now available on the Windows Phone 7 marketplace!&lt;br /&gt;&lt;br /&gt;This'll be my entry to the &lt;a href="http://www.microsoft.com/australia/devvsdev"&gt;DevVsDev&lt;/a&gt; competition. SatView is a satellite tracker and orbit predictor that allows you to track one of 1300+ different satellites as they orbit the Earth. Here's the marketing spiel from my site:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;SatView is a realtime satellite tracker   and orbit predictor. Track  satellite positions, determine visibility,   and calculate coordinates  of over 1300 different satellites.&lt;/p&gt;         &lt;p&gt;Included   with SatView are both 2D and 3D viewing modes,  allowing you to view the   orbital trajectories of satellies from space  or projected onto a map.   SatView can also use your phone's GPS system  to determine visibility and   to calculate satellite passes over your  location. SatView is   ideal for budding astronomers and amateurs alike.  &lt;/p&gt;         &lt;p&gt;Features:&lt;/p&gt;         &lt;ul&gt;&lt;li&gt;1300+ different trackable satellites&lt;/li&gt;&lt;li&gt;Orbit prediction with adjustable time controls&lt;/li&gt;&lt;li&gt;GPS and location services support&lt;/li&gt;&lt;li&gt;Determine all visible satellites from your current location&lt;/li&gt;&lt;li&gt;Calculate next visible passes of a chosen satellite over your location&lt;/li&gt;&lt;li&gt;Search function for finding satellites by name or catalog number&lt;/li&gt;&lt;li&gt;2D and 3D orbit viewing modes&lt;/li&gt;&lt;li&gt;Topographic and geocentric coordinates&lt;/li&gt;&lt;li&gt;Automatic updates for latest satellite orbital data&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I'll admit that this is a pretty niche app. But still, I think it's cool. :) And remember, if you don't already know, &lt;a href="http://www.microsoft.com/australia/devvsdev"&gt;DevVsDev&lt;/a&gt; closes in just a few weeks, so you'd better submit fast!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;h2&gt;only US$1.29&lt;/h2&gt;&lt;/center&gt;&lt;a href="http://social.zune.net/redirect?type=phoneApp&amp;amp;id=452f46af-8736-e011-854c-00237de2db9e"&gt;&lt;img src="http://microngamestudios.com/images/nextwar_wp7/wp7_English_278x92_blue.png" style="margin: 0pt auto; display: block;" alt="Download for Windows Phone 7" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;center&gt;Zune client software required.&lt;/center&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/satview.html"&gt;&lt;h2&gt;More information at microngamestudios.com&lt;/h2&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-5837538421919614655?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/5837538421919614655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=5837538421919614655' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5837538421919614655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5837538421919614655'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/02/satview-for-windows-phone-7-released.html' title='SatView for Windows Phone 7 Released!'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-5746872830537811380</id><published>2011-02-12T23:19:00.004+11:00</published><updated>2011-02-12T23:31:37.266+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DevVsDev'/><category scheme='http://www.blogger.com/atom/ns#' term='Dev Vs Dev'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Super-secret projects</title><content type='html'>Apparently I suck at pressing "publish post". I pressed "save" instead of "publish" on that last post, so it's a few days late. Luckily, Blogger lets you arbitrarily set dates on your blog posts. :P&lt;br /&gt;&lt;br /&gt;Over the past few weeks I've been working on my entry to the Microsoft &lt;a href="http://www.microsoft.com/australia/devvsdev"&gt;DevVsDev&lt;/a&gt; competition. DevVsDev is a Windows Phone 7 application development contest run by Microsoft for Australian developers. Basically the gist of it is this: write an app for WP7. Submit it. Best app wins a trip to MIX11 in Las Vegas valued at $10k, and the next 5 runners up get free Windows Phone 7's. Entries close 28th February 2011, which is in just a couple of weeks. If you want to enter, you'd better act fast!&lt;br /&gt;&lt;br /&gt;Today, I submitted my application to marketplace. Once it passes certification, I'll be entering it into DevVsDev. What is my app? Well, I'll reveal more once it hits marketplace. Is it good enough to win? Heck, I dunno. It's just something I've been working on in my free time, and I have no idea what my competition is. But seeing as the developer tools have been downloaded over &lt;a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/02/04/windows-phone-developer-tools-january-update.aspx"&gt;1 million&lt;/a&gt; times, I expect to see some pretty amazing apps in DevVsDev.&lt;br /&gt;&lt;br /&gt;Regardless of whether I win anything or not, developing for WP7 is just plain &lt;span style="font-style:italic;"&gt;fun&lt;/span&gt;. If you haven't already considered it, I would highly recommend submitting an entry and having a chance at one of 6 fabulous prizes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-5746872830537811380?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/5746872830537811380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=5746872830537811380' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5746872830537811380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5746872830537811380'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/02/super-secret-projects.html' title='Super-secret projects'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4881978206797793831</id><published>2011-02-10T12:04:00.005+11:00</published><updated>2011-02-12T23:16:27.719+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Microsoft Student Partner Summit 2011</title><content type='html'>Now that the MSP bootcamp is over, I guess I can officially call myself a Microsoft Student Partner. :D&lt;br /&gt;&lt;br /&gt;Yesterday, I got back from the MSP 2011 Bootcamp. This is my first time as a Microsoft Student Partner, and the experience was certainly one to remember.&lt;br /&gt;&lt;br /&gt;On Monday Microsoft flew us all to Sydney for a 3-day summit at their North Ryde Headquarters. 38 MSPs from all over Australia were there, representing 28 universities. I got to meet a lot of awesome fellow MSPs, as well as a bunch of equally awesome Microsofties.&lt;br /&gt;&lt;br /&gt;Throughout the three days were a bunch of introductions, presentations, workshops, activities, and fun to be had all round. Oh, and free stuff. Lots of it. But maybe that's a post for another day.&lt;br /&gt;&lt;br /&gt;Before the bootcamp, I was excited to be an MSP. Now? I'm PUMPED. I won't reveal just yet what's planned, but it's going to be an amazing year. I look forward to it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4881978206797793831?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4881978206797793831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4881978206797793831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4881978206797793831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4881978206797793831'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2011/02/microsoft-student-partner-summit-2011.html' title='Microsoft Student Partner Summit 2011'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8768532787180332467</id><published>2010-12-05T08:11:00.002+11:00</published><updated>2010-12-05T08:12:56.223+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Windows Phone 7 Update 1.01 Released</title><content type='html'>NextWar for Windows Phone 7 received a small update today, fixing a small issue with the sliders in the options menu and updating the marketplace/tile icons. The update should be applied automatically the next time you start the game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8768532787180332467?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8768532787180332467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8768532787180332467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8768532787180332467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8768532787180332467'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/12/nextwar-windows-phone-7-update-101.html' title='NextWar Windows Phone 7 Update 1.01 Released'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-5662243256161779536</id><published>2010-10-17T14:28:00.011+11:00</published><updated>2010-10-17T17:01:13.831+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: The Quest for Earth released for Windows Phone 7!</title><content type='html'>After many months of development and testing, NextWar: The Quest for Earth is now up on the Windows Phone 7 marketplace!&lt;br /&gt;&lt;br /&gt;If you've got a Windows Phone 7, check it out!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;h2&gt;only US$2.99&lt;/h2&gt;&lt;/center&gt;&lt;a href="http://social.zune.net/redirect?type=phoneApp&amp;id=b56a3da7-87d5-df11-a844-00237de2db9e"&gt;&lt;img src="http://microngamestudios.com/images/nextwar_wp7/wp7_English_278x92_blue.png" style="margin: 0 auto 0 auto; display:block;" alt="Download for Windows Phone 7" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;center&gt;Zune client software required.&lt;/center&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/nextwar_wp7.html"&gt;&lt;h2&gt;More information at microngamestudios.com&lt;/h2&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-5662243256161779536?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/5662243256161779536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=5662243256161779536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5662243256161779536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5662243256161779536'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/10/nextwar-quest-for-earth-released-for.html' title='NextWar: The Quest for Earth released for Windows Phone 7!'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-471199004214969398</id><published>2010-10-02T17:12:00.004+10:00</published><updated>2010-10-02T17:18:18.886+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Trailer for Windows Phone 7</title><content type='html'>Just released the trailer for &lt;a href="http://microngamestudios.com/nextwar_wp7.html"&gt;Nextwar&lt;/a&gt; on Windows Phone 7. See it below!&lt;br /&gt;&lt;br /&gt;&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/qOSwVqf3fxI?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/qOSwVqf3fxI?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://microngamestudios.com/files/nextwar_wp7/NextWar_Trailer_WP7.wmv"&gt;Download Link (right-click, save-as) (.wmv, 19.9mb)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-471199004214969398?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/471199004214969398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=471199004214969398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/471199004214969398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/471199004214969398'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/10/nextwar-trailer-for-windows-phone-7.html' title='NextWar Trailer for Windows Phone 7'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8074344090480363038</id><published>2010-09-06T22:48:00.005+10:00</published><updated>2010-09-06T22:53:20.915+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: Now in Landscape!</title><content type='html'>Work continues. Newest feature: landscape support!&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://microngamestudios.com/images/nextwar_wp7/landscape1.jpg"&gt;&lt;img src="http://microngamestudios.com/images/nextwar_wp7/landscape1_sm.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://microngamestudios.com/images/nextwar_wp7/landscape2.jpg"&gt;&lt;img src="http://microngamestudios.com/images/nextwar_wp7/landscape2_sm.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://microngamestudios.com/images/nextwar_wp7/landscape3.jpg"&gt;&lt;img src="http://microngamestudios.com/images/nextwar_wp7/landscape3_sm.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Next on the to-do list: two-finger rotate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8074344090480363038?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8074344090480363038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8074344090480363038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8074344090480363038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8074344090480363038'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/09/nextwar-now-in-landscape.html' title='NextWar: Now in Landscape!'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3341952092853906805</id><published>2010-09-03T22:13:00.016+10:00</published><updated>2010-09-04T21:15:47.340+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><title type='text'>Pinch zooming using XNA4 on WP7: Getting it right</title><content type='html'>&lt;span style="font-style: italic;font-size:130%;" &gt;If you don't care about the explanations and just want to skip to the code, &lt;a href="#code"&gt;click here.&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pinch-to-zoom is one of the basic multi-touch gestures. It's an intuitive way to zoom in/out and is found pretty much anywhere multi-touch is found. It's really easy to implement but it seems that more often than not, people get it wrong. Unfortunately, even &lt;a href="http://blogs.msdn.com/b/nicgrave/archive/2010/07/12/touch-gestures-on-windows-phone-7.aspx"&gt;Nick Gravelyn's&lt;/a&gt; &lt;a href="http://creators.xna.com/en-us/sample/gestures"&gt;touch-gesture sample&lt;/a&gt; on the XNA website got it wrong. (But to be fair, the sample was more about demonstrating the API than what you could do with it.)&lt;br /&gt;&lt;br /&gt;Let's first take a look at how pinch-to-zoom is supposed to work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;The Gold Standard&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you have an iPhone or iPod Touch, pull it out now and view a big image. Find two "landmarks" in the image: spots which are easy to precisely identify in an image - for example the tip of a skyscraper or somebody's nose. Find two of these spots, place a finger on each and pinch together. As you pinch you'll notice that your two chosen landmark spots still remain in place underneath your fingers.&lt;br /&gt;&lt;br /&gt;This is how pinch-to-zoom is supposed to work. Each of your two fingers should act as an "anchor" on the image - once the two fingers are pressed on the screen, the points on the image underneath each finger should stay stationary relative to their respective finger.&lt;br /&gt;&lt;br /&gt;Okay, so maybe that explanation wasn't very clear. Maybe an image or two will help:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://microngamestudios.com/images/blog/pinch-narrow.jpg" /&gt;&lt;br /&gt;&lt;img src="http://microngamestudios.com/images/blog/pinch-wide.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Now you can see what I mean: the points on the image underneath each finger don't move relative to the finger. After the gesture is complete our friendly koala's eye is still under the thumb and the top of his head is still under the index finger.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Implementing it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Okay, so how do you actually implement that? The easiest way would be to use matrices - using matrices you can easily define the center of scaling to handle much of this for you. But the SpriteBatch.Draw method doesn't allow you to specify a transformation matrix - so you have to make do specifying a scale and a position.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Scaling&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Scaling is pretty simple. In your GestureSample, you get position and a delta for each finger. If you subtract the delta from the position, you have the previous position of each finger. And the amount you need to scale by is simply the ratio of the old and new distances between each finger.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;position1 = position of finger 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;position2 = position of finger 2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;delta1 = delta of finger 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;delta2 = delta of finger 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;oldPosition1 = position1 - delta1&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;oldPosition2 = position2 - delta2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;newDistance = dist(position1, position2)&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;oldDistance = dist(oldPosition1, oldPosition2)&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;scaleFactor = newDistance / oldDistance;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;scaleFactor&lt;/span&gt; is the amount you &lt;span style="font-weight: bold;"&gt;multiply&lt;/span&gt; your object's scale by, not the absolute scale of your object. In other words, it doesn't determine your object's scale directly, only how much to &lt;span style="font-weight: bold;"&gt;change &lt;/span&gt;your object's scale by. In pseudocode:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;float scaleFactor = GetScaleFactor();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;obj.Scale *= scaleFactor;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;renderer.Draw(obj.Position, obj.Scale);&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Translation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Translation is a little bit trickier. We've found the amount to scale our object by, but remember that the points underneath each finger shouldn't move relative to the finger - those points should be "anchored" to each finger. So that means we need to translate the object in such a way that whatever was under each finger &lt;span style="font-weight: bold;"&gt;before &lt;/span&gt;the pinch motion are &lt;span style="font-weight: bold;"&gt;still &lt;/span&gt;under the finger afterwards. Again, in pseudocode:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;newPos1 = position1 - (oldPosition1 - obj.Position) * scaleFactor;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;newPos2 = position2 - (oldPosition2 - obj.Position) * scaleFactor;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;obj.Position = midpoint(newPos1, newPos2);&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note: &lt;/span&gt;this assumes that &lt;span style="font-family:courier new;"&gt;obj.Position&lt;/span&gt; is in screen-space!&lt;br /&gt;&lt;br /&gt;Where the definitions of &lt;span style="font-family:courier new;"&gt;position1&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;position2&lt;/span&gt;, etc. are the same as previously.&lt;br /&gt;&lt;br /&gt;An explanation:&lt;br /&gt;&lt;br /&gt;Ignore one of the fingers for now - consider only one of the two fingers. You know that the finger moved by some amount this frame, and the object has also been scaled by some amount this frame. And you want to ensure that the point on the object underneath the finger previously is still underneath the finger now.&lt;br /&gt;&lt;br /&gt;All that the code does is find the difference between the object's position and the finger's old position, scales it according to the scaling factor, then adds it to the finger's new position. But wait! There are two fingers - which one do we use? Well, both, actually - which is why we take the midpoint of the two possible new positions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's it. If you apply these simple formulae for the scaling and translation of your objects, your pinch-zoom behaviour will be correct and will "feel" right to your user. Reading and translating all that obtuse prose can be a pain, I know, so I've also provided some sample code that you can use.&lt;br /&gt;&lt;br /&gt;&lt;a name="code"&gt;&lt;/a&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;The Code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There isn't much to it, really. I've provided a static class PinchZoom which contains the functions necessary to implement pinch zooming, as well as a sample project. You'll need a multi-touch capable monitor or an actual WP7 device to test it, of course. Alternatively you can try &lt;a href="http://gamewithjosh.blogspot.com/2010/07/xna-multi-touch-input-on-windows-phone.html"&gt;this&lt;/a&gt; excellent multi-touch simulator drop-in component.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://microngamestudios.com/files/pinchzoom/PinchZoom.zip"&gt;PinchZoom.zip Sample project (789KB)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://microngamestudios.com/files/pinchzoom/PinchZoom.cs"&gt;PinchZoom.cs (5KB)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here it is in action:&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/hO2-GsR7TL0?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/hO2-GsR7TL0?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="480"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3341952092853906805?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3341952092853906805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3341952092853906805' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3341952092853906805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3341952092853906805'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/09/pinch-zooming-using-xna4-on-wp7-getting.html' title='Pinch zooming using XNA4 on WP7: Getting it right'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2033250340701573346</id><published>2010-08-27T21:59:00.003+10:00</published><updated>2010-08-31T22:09:35.529+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wp7dev'/><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar for WP7 at TechEd</title><content type='html'>If you were at TechEd Australia 2010, you might have seen NextWar at the keynote on Tuesday. Mad props to &lt;a href="http://twitter.com/dglover"&gt;Dave Glover&lt;/a&gt; for doing that - getting it out there in front of 3000 pairs of eyes was certainly some nice free publicity. ;)&lt;br /&gt;&lt;br /&gt;At &lt;a href="http://www.istartedsomething.com/20100824/local-windows-phone-7-apps-showcased-at-teched/"&gt;istartedsomething&lt;/a&gt;, Long Zheng (coincidentally also an MHS old boy) has a photostream that includes &lt;a href="http://www.flickr.com/photos/longzheng/sets/72157624671936959/"&gt;a couple of photos of NextWar&lt;/a&gt; running on prototype hardware.&lt;br /&gt;&lt;br /&gt;Dave lent me his TabletPC and his prototype WP7 device so I could test on it before the demo at TechEd. It was only prototype hardware and not representative of the final product, but it ran amazingly well. Prototype or not, it looks amazingly good running on an actual device!&lt;br /&gt;&lt;br /&gt;There'll be some more updates coming soon, so stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2033250340701573346?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2033250340701573346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2033250340701573346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2033250340701573346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2033250340701573346'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/08/nextwar-for-wp7-at-teched.html' title='NextWar for WP7 at TechEd'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7375719569419573433</id><published>2010-06-23T12:45:00.004+10:00</published><updated>2010-06-23T13:01:50.342+10:00</updated><title type='text'>App My State</title><content type='html'>I'm proud to announce that my app for Windows Mobile 6 and 6.5 devices, &lt;span style="font-style:italic;"&gt;&lt;a href="http://metropolitanmelbourne.com/"&gt;Metropolitan Melbourne&lt;/a&gt;&lt;/span&gt;, has &lt;a href="http://www.premier.vic.gov.au/app-my-state/the-winners.html"&gt;won second prize&lt;/a&gt; in the Victorian Government's App My State competition!&lt;br /&gt;&lt;br /&gt;On Monday I went to the awards event at the State Library of Victoria to accept the prize. Premier of Victoria John Brumby was there to present the awards, and it was interesting to see the other entries and winners. Well done to all who entered! I won a 17" Macbook Pro, a 16GB iPhone 3GS, a 250GB PS3 Slim, a JB Hi-Fi gift card, and a MinoHD 8GB flip video camcorder. The prizes have a total value of $5000.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;About Metropolitan Melbourne:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Metropolitan Melbourne&lt;/span&gt; ("Metro Melbourne" for short) is an app for Windows Mobile 6 and 6.5 phones. It features train timetables for all metropolitan Melbourne train services presented in a simple and easy-to-use interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Features:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; View metropolitan train network maps&lt;br /&gt;&lt;li&gt; Use the in-built journey planner to generate the fastest route between two stations&lt;br /&gt;&lt;li&gt; Browse timetables for all train stations across all lines&lt;br /&gt;&lt;li&gt; See which trains are next to depart from any particular station&lt;br /&gt;&lt;li&gt; View departure and arrival times for a particular train service&lt;br /&gt;&lt;li&gt; Save your favourite stations in a quick-access favourites list&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Downloads and usage instructions for Metropolitan Melbourne can be found on its website: &lt;a href="http://metropolitanmelbourne.com/"&gt;http://metropolitanmelbourne.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7375719569419573433?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7375719569419573433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7375719569419573433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7375719569419573433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7375719569419573433'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2010/06/app-my-state.html' title='App My State'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7214879281682054217</id><published>2009-10-23T08:43:00.002+11:00</published><updated>2009-10-23T09:25:05.320+11:00</updated><title type='text'>Informatics fail</title><content type='html'>So one of the subjects I'm doing this semester is Informatics 2. It's basically an introductory programming/comp.sci course. Coming up is a major major assessment, worth 25% of our final unit mark. For this assessment, we have to write a web application to search/view movies from a database.&lt;br /&gt;&lt;br /&gt;Simple enough, and the code is fairly trivial. I was working on code to scrape Amazon.com for movie images, so we could display them alongside the search results. Now, we have to use this online system called IVLE, which was written by the university (apparently). IVLE is essentially an online web-based IDE for developing in Python. It stores your files on a central server at the uni, and you develop your scripts through your browser and execute them remotely on the university's servers.&lt;br /&gt;&lt;br /&gt;On the surface it sounds pretty good. If only the damn thing actually worked.&lt;br /&gt;&lt;br /&gt;You see, IVLE is so buggy that at times it becomes near-unusable. Sometimes IVLE will incorrectly copy/paste text. Sometimes it won't properly save your work, causing you to lose data. And every now and then it has a habit of inserting phantom text into your code at random, causing all sorts of weirdness.&lt;br /&gt;&lt;br /&gt;But those problems I can live with. Those bugs can be worked around with enough effort. No, the real problem is that &lt;span style="font-weight:bold;"&gt;IVLE fails at doing the one thing it was designed for: running scripts&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I can't do any work if I can't actually run my scripts through IVLE. If the IDE is crappy and buggy, I can work around that with enough effort. But this is just ridiculous.&lt;br /&gt;&lt;br /&gt;So I'm trying to write a python script to scrape Amazon for movie images. All it involves is unpickling about 4200 files, downloading a page from Amazon, scraping the page for an image link, then downloading the image to file.&lt;br /&gt;&lt;br /&gt;Firstly, doing it one by one is too slow, since urllib is synchronous (blocking). So I used Python threading to run a bunch of threads to scrape multiple images in parallel. Problem solved, right? Well, IVLE can't even handle that. Creating a measly 32 threads doesn't work - I get a "cannot create any more threads" exception. You're kidding me, right? I had to drop it down to 16 simultaneous threads.&lt;br /&gt;&lt;br /&gt;Well, 16 threads should still run pretty fast, right? Sure. IF IVLE ACTUALLY ALLOWED ME TO RUN MY SCRIPT. You see, IVLE is so buggy that 90% of the time, it throws up a "internal Python console error". And then the Python console becomes unusable - resetting it has no effect (it just throws up another internal console error).&lt;br /&gt;&lt;br /&gt;So I have to log out of IVLE, and log back in again. This time I successfully start the script, but I soon discover that there's a minor bug in my program, so I hit "interrupt" to stop the program. I fixed the bug, and then try running it again. OH WAIT, I SUPPOSE IVLE DOESN'T ACTUALLY LIKE PEOPLE ACCOMPLISHING ANY WORK. It throws another "internal Python console error".&lt;br /&gt;&lt;br /&gt;Now rinse and repeat this experience. &lt;span style="font-weight:bold;"&gt;Many, many times&lt;/span&gt;. I spent 4 hours battling with IVLE and it's incessant internal Python console errors. Obviously, IVLE either doesn't like my script or it handles creation/destruction of threads really, really badly.&lt;br /&gt;&lt;br /&gt;Now, after spending an afternoon battling with IVLE, I finally got it to run without any problems. And after a few minutes, with only half the images downloaded, IVLE threw an error saying that I'd exceeded the CPU time limit. CPU time limits are fair enough, the simple solution is just run the script a second time and skip over the work done in the first pass.&lt;br /&gt;&lt;br /&gt;Wait, you mean I have to run the script a second time? And go through all that pain &lt;span style="font-style:italic;"&gt;again&lt;/span&gt;!? Already I can hear IVLE laughing at me from beyond the deepest gates of Hell as I vainly try to finish my work before the due date.&lt;br /&gt;&lt;br /&gt;Eugh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7214879281682054217?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7214879281682054217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7214879281682054217' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7214879281682054217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7214879281682054217'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/10/informatics-fail.html' title='Informatics fail'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3330880074340067421</id><published>2009-09-20T15:51:00.004+10:00</published><updated>2009-09-20T16:11:39.509+10:00</updated><title type='text'>An overly elaborate alarm clock</title><content type='html'>The mid-semester break has just started, and I thought I'd celebrate my 2 weeks of freedom by creating a pointlessly elaborate alarm clock.&lt;br /&gt;&lt;br /&gt;The problem: I can't get up in the morning. I don't have an alarm clock, and I'm too cheap/lazy to buy one.&lt;br /&gt;&lt;br /&gt;Solution: Write an alarm clock program to run on my desktop.&lt;br /&gt;&lt;br /&gt;I use 2 Dell 24" 2408WFP LCDs as part of my desktop - which sits opposite my bed. So I decided to make an alarm clock out of them.&lt;br /&gt;&lt;br /&gt;First thing's first: turning on my PC. Every night I put my desktop to sleep, since it's far more convenient than shutting it down. Luckily, Windows Vista's task scheduler allows for waking the computer from sleep in order to run scheduled tasks. Perfect!&lt;br /&gt;&lt;br /&gt;Next, the alarm clock program. Using task scheduler, it's set to run every morning at the pre-set time. Once the computer wakes and the program runs, this is what I'm presented with:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://img36.imageshack.us/img36/4107/alarm.png"&gt;&lt;img src="http://img36.imageshack.us/img36/4107/alarm.th.png" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;On the left monitor I have a big polar clock, which I shamelessly stole from &lt;a href="http://blog.pixelbreaker.com/polarclock/"&gt;pixelbreaker.com&lt;/a&gt;. Although the idea belongs to someone else, this implementation is my own. On the right monitor I have some daily weather information pulled directly from the &lt;a href="http://www.bom.gov.au/"&gt;Bureau of Meteorology&lt;/a&gt;'s data feeds. When getting dressed in the morning it always helps to know the current weather forecasts for the day.&lt;br /&gt;&lt;br /&gt;When the program starts, it starts playing music (from my music collection) to wake me up. It also makes sure to set the system master volume automatically to make sure it's loud enough to get be out of bed.&lt;br /&gt;&lt;br /&gt;The program was written in C# using XNA Game Studio 3.1. What a way to waste a weekend. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3330880074340067421?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3330880074340067421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3330880074340067421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3330880074340067421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3330880074340067421'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/09/overly-elaborate-alarm-clock.html' title='An overly elaborate alarm clock'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-6834379201316676829</id><published>2009-08-12T18:16:00.005+10:00</published><updated>2009-08-12T20:17:07.613+10:00</updated><title type='text'>Damnit, Melbourne</title><content type='html'>Maybe it's just me, but Melbourne Uni seems really disorganised. Just the other day, I was trying to find more information about the MSDN Academic Alliance, which allows staff and students of IT-related departments to recieve free Microsoft software.&lt;br /&gt;&lt;br /&gt;So to find out about the MSDNAA, I needed to contact the department which teaches IT-related subjects. There are two departments, though - the Departement of Information Systems and the Department of Computer Science and Software Engineering. The Department of Information Systems falls under the Faculty of Science, while the Department of Computer Science and Software Engineering falls under the Faculty of Engineering.&lt;br /&gt;&lt;br /&gt;I'm currently enrolled in a Bachelor of Science, so I suppose I should contact the Department of Information Systems since that's the department that falls under the Faculty of Science. But hold on, I'll be majoring in Computer Science which means that I should belong to the Department of Computer Science and Software Engineering. But the actual subjects that lead to this major (Informatics 1&amp;2) are administered by the Department of Information Systems.&lt;br /&gt;&lt;br /&gt;So to sort this confusion out, I asked one of the subject co-ordinators for Informatics 2. He didn't know about the MSDNAA specifically, so he referred me to the Information Services division. I emailed them through Student IT Support, and they forwarded my request to the university's IT Licensing Group. The IT Licensing Group apparently told Student IT Support that the university's MSDNAA subscription only allows for the software to be installed on "University Assets" and not personal workstations.&lt;br /&gt;&lt;br /&gt;That appeared contrary to the terms of the MSDNAA subscription, so I contacted the Melbourne University Computer Students Association (MUCSA) who sell legitimate copies of Windows Vista/XP to students for a nominal fee of $10. I asked them where they got their keys from, and they told me that they went through MSDNAA (via. one of the departments). This means that Melbourne Uni &lt;span style="font-weight:bold;"&gt;does&lt;/span&gt; have an MSDNAA subscription, and &lt;span style="font-weight:bold;"&gt;is&lt;/span&gt; allowed to distribute software to students, contradicting what the IT Licensing Group told me.&lt;br /&gt;&lt;br /&gt;Now after wading through that quagmire, I didn't find what I was looking for, don't have any more information, and don't know what's going on. Nevertheless, I've contacted the subject co-ordinator for Informatics 2 again, who might be able to shed some more light on all this. I await his reply.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-6834379201316676829?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/6834379201316676829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=6834379201316676829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6834379201316676829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6834379201316676829'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/08/damnit-melbourne.html' title='Damnit, Melbourne'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-285471802940914589</id><published>2009-07-30T20:29:00.004+10:00</published><updated>2009-07-30T20:35:20.910+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar now available in more regions; cheaper</title><content type='html'>With the new updates to XNA and Xbox Live &lt;strike&gt;Community&lt;/strike&gt; Indie Games, games are now available for sale in Germany, Japan, Singapore and Sweden. I've updated NextWar so that it can now be sold in these regions. So if you live in these regions, and are itching to play Tower Defence on your Xbox 360, check out NextWar!&lt;br /&gt;&lt;br /&gt;Also, with the introduction of the new pricepoints (80MSP, 240MSP and 400MSP, corresponding to $1, $3, and $5 respectively), I've decided to drop the price of NextWar to 80MSP. So if you were holding off buying NextWar or didn't think it was worth 200MSP, you might want to reconsider! NextWar is now in the Xbox Live version of the $1 bargain bin. :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/nextwar_x360.html"&gt;NextWar: The Quest for Earth official site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marketplace.xbox.com/en-US/games/media/66acd000-77fe-1000-9115-d802585501d3/"&gt;Xbox Live Marketplace link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-285471802940914589?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/285471802940914589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=285471802940914589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/285471802940914589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/285471802940914589'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/07/nextwar-now-available-in-more-regions.html' title='NextWar now available in more regions; cheaper'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4101839168804984326</id><published>2009-07-02T15:24:00.010+10:00</published><updated>2009-07-05T14:16:19.026+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>How well did NextWar really do?</title><content type='html'>Well, it's been 3 months since the release of NextWar: The Quest for Earth over Xbox Live Community Games. How well did it really do?&lt;br /&gt;&lt;br /&gt;I'll let the graphs speak for themselves first:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://img232.imageshack.us/img232/2639/salestrialslog.png"&gt;&lt;img src="http://img232.imageshack.us/img232/2639/salestrialslog.th.png" /&gt;&lt;/a&gt; &lt;a href="http://img219.imageshack.us/img219/9554/salestrials.png"&gt;&lt;img src="http://img219.imageshack.us/img219/9554/salestrials.th.png" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The sales graph curved pretty much exactly how I expected it: an exponential decrease immediately after release, then dropping off a cliff after the game fell off the New Releases/Most Popular lists. Once that happened, sales trickled down to single digits per day.&lt;br /&gt;&lt;br /&gt;Overall statistics:&lt;br /&gt;&lt;blockquote&gt;Downloads to date: 14572&lt;br /&gt;Sales to date: 2703&lt;br /&gt;Conversion Rate: 18.55%&lt;br /&gt;Total revenue: US$4578.88&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It did reasonably well compared to many other Community Games - but the overall conclusion is "don't quit your day job". Making a game and selling it on Community Games can be fun as a hobby, but it's not viable as a full-time job. This is essentially echoed by many other developers who have released games on XBLCG. Nevertheless, despite only being a minor success, the amount of money generated by NextWar's sales (however small) is still nice for something that I put together in my free time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Future&lt;/span&gt;&lt;br /&gt;So what lies ahead for Micron Game Studios and the future of my hobbyist game development?&lt;br /&gt;&lt;br /&gt;Well, I'm doing this for fun and not for the money, so I think I'll be making another game regardless of how I think NextWar did in terms of sales.&lt;br /&gt;&lt;br /&gt;There are a few viable game designs I'm batting around right now, so stay tuned for more stuff coming out of Micron Game Studios in the coming months!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4101839168804984326?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4101839168804984326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4101839168804984326' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4101839168804984326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4101839168804984326'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/07/how-well-did-nextwar-really-do.html' title='How well did NextWar really do?'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8493319250321292148</id><published>2009-05-06T09:18:00.000+10:00</published><updated>2009-05-06T09:19:39.495+10:00</updated><title type='text'>Bluejacking</title><content type='html'>I'm on the train. I think somebody just tried to &lt;a href="http://en.wikipedia.org/wiki/Bluejacking"&gt;bluejack&lt;/a&gt; me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8493319250321292148?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8493319250321292148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8493319250321292148' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8493319250321292148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8493319250321292148'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/05/bluejacking.html' title='Bluejacking'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3726948247497541193</id><published>2009-05-05T09:46:00.003+10:00</published><updated>2009-05-05T09:59:34.047+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Uni'/><title type='text'>Getting Past the Melbourne Uni Proxy</title><content type='html'>Melbourne University has a slightly draconian policy for use of their internet on campus. All traffic must go through an HTTP proxy; basically everything besides port 80 (for regular HTTP) and port 443 (for HTTPS) is blocked.&lt;br /&gt;&lt;br /&gt;It means I can't access my LAN, my home computers, or my Perforce server. I first tried Hamachi, which is a free (as in beer) piece of software that allows you to quickly and very easily set up a VPN. Start the software, connect to a network, and you're good to go. It worked fine outside the uni. But it's tunnelling capabilities were... limited. Hamachi supports HTTP tunnelling, but not in a peer-to-peer fashion. Instead, connections had to go through Hamachi's private "relay servers". For the free version of Hamachi, this was incredibly slow (and unreliable, in my experience). The commercial (ie: paid) version is apparently faster, but I wasn't prepared to pay ~$50/year to be able to access my home LAN from uni.&lt;br /&gt;&lt;br /&gt;Next try: OpenVPN. OpenVPN supports HTTP tunnelling out of the box, and was relatively painless to configure (though not nearly as easy as Hamachi). I installed OpenVPN on the server at home, which is always on and always connected to the internet. Using a bridged network, OpenVPN acts as a virtual gateway to my LAN at home. I set it up to listen for TCP on port 443.&lt;br /&gt;&lt;br /&gt;I installed OpenVPN as well, and set it up to go through the Melbourne Uni proxy, connecting to my home server (via. dynamic DNS provided by dyndns.org) through port 443. And lo and behold, it works. The proxy can't tell the difference between regular HTTPS traffic and the encrypted OpenVPN traffic, and I can now access my LAN from uni.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3726948247497541193?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3726948247497541193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3726948247497541193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3726948247497541193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3726948247497541193'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/05/getting-past-melbourne-uni-proxy.html' title='Getting Past the Melbourne Uni Proxy'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3226645964077154449</id><published>2009-04-21T18:22:00.000+10:00</published><updated>2009-04-21T18:23:04.646+10:00</updated><title type='text'>New PC</title><content type='html'>Well, I bit the bullet and bought myself a new PC. Specifications are as follows:&lt;br /&gt;&lt;br /&gt;Intel Core i7 920&lt;br /&gt;Asus P6T motherboard&lt;br /&gt;12GB (6x2GB) Kingston DDR3-1333&lt;br /&gt;Asus HD4870 1GB&lt;br /&gt;Lian-Li PC-A77 full tower case&lt;br /&gt;Noctua NH-U12P CPU cooler&lt;br /&gt;&lt;br /&gt;Kept the DVD drives and 1.5TB worth of hard drives from my old PC. Total cost? About AUD$1900 (USD$1330) all up.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Overclocking&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Initial results for overclocking the i7 seemed promising - it shipped stock with a core voltage (vcore) of 1.2V. The default range of voltages for the i7 920 is 0.8v - 1.375v, according to Intel. The CPU core is a c0/c1 stepping, according to CPU-Z. I didn't really expect to be able to get a new D0 stepping, since it's way too new for the local retailers here to stock it.&lt;br /&gt;&lt;br /&gt;Using the stock voltage, I was able to get it to run at 3.6ghz stable. At 1.375v, I could run it at 3.8ghz stable. I reached 4ghz only by increasing voltage to 1.44v. 1.44v was considered far beyond safe for regular usage - the CPU was hitting &gt;87C load, and that's using one of the highest performing air coolers on the market (the Noctua NH-U12P).&lt;br /&gt;&lt;br /&gt;I eventually settled for 1.375v and 3.8ghz. With a multiplier of 20x, that means a BCLK of 190mhz. The cheap Kingston ValueRAM also reached a surprising overclock - it's currently running at 760mhz (1520mhz DDR), which is a 14% overclock over the stock 666mhz (1333mhz DDR). And that's at stock voltage of 1.5v, and stock latency of CL9.&lt;br /&gt;&lt;br /&gt;That's one mighty fast CPU - a definite upgrade over my ageing Core 2 Duo E6600 circa 2006.&lt;br /&gt;&lt;br /&gt;Didn't bother overclocking the video card; it's plenty fast enough for pretty much anything except Crysis.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Old PC&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My old hardware won't be going to waste. there's still a perfectly good E6600 and 4GB DDR2 RAM in there. It'll replace the network server I have here at home; it's currently running on a ~2001 era Northwood Pentium 4 with 512mb DDR. The Core 2 should be a significant upgrade for the server, which runs stuff like my Perforce server and media storage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3226645964077154449?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3226645964077154449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3226645964077154449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3226645964077154449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3226645964077154449'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/04/new-pc.html' title='New PC'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2672448100945494089</id><published>2009-04-09T08:51:00.001+10:00</published><updated>2009-04-09T08:55:02.369+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: The Quest for Earth for Xbox 360 Version 1.01 Released</title><content type='html'>Hi all.&lt;br /&gt;&lt;br /&gt;An updated version of &lt;a href="http://www.microngamestudios.com/nextwar_x360.html"&gt;NextWar: The Quest for Earth&lt;/a&gt; for the Xbox 360 has been released to Xbox LIVE Community Games. Version 1.01 fixes the "Send Next Wave" crash bug.&lt;br /&gt;&lt;br /&gt;If you've experienced this bug, you should redownload the game from Xbox Live Marketplace. Thanks to all who noticed and reported this bug, I wouldn't have been able to fix it without you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2672448100945494089?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2672448100945494089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2672448100945494089' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2672448100945494089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2672448100945494089'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/04/nextwar-quest-for-earth-for-xbox-360.html' title='NextWar: The Quest for Earth for Xbox 360 Version 1.01 Released'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2375680016243614755</id><published>2009-04-03T17:22:00.001+11:00</published><updated>2009-04-03T17:24:34.547+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Developer Q&amp;A</title><content type='html'>I recently did a short interview for &lt;a href="http://xblaratings.com/"&gt;xblaratings.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can read it &lt;a href="http://xblaratings.com/developer-qaa/664-nextwar-the-quest-for-earth-developer-qaa"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2375680016243614755?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2375680016243614755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2375680016243614755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2375680016243614755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2375680016243614755'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/04/nextwar-developer-q.html' title='NextWar Developer Q&amp;A'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2017864463378178180</id><published>2009-03-30T21:23:00.002+11:00</published><updated>2009-03-30T21:26:31.361+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Crash Bug</title><content type='html'>A crash bug involving the "Send Next Wave" button has been identified and a workaround available. If you are experiencing this problem, please see the problem page at the Micron Game Studios website:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/nextwar_x360_bug1.html"&gt;NextWar for Xbox 360: "Send Next Wave" Crash Bug&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2017864463378178180?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2017864463378178180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2017864463378178180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2017864463378178180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2017864463378178180'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/03/nextwar-crash-bug.html' title='NextWar Crash Bug'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1266156532536618875</id><published>2009-03-28T10:42:00.002+11:00</published><updated>2009-03-28T10:48:02.021+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: The Quest for Earth released for the Xbox 360!</title><content type='html'>I'm proud to announce that NextWar: The Quest for Earth is now available for download on Xbox Live Community Games!&lt;br /&gt;&lt;br /&gt;It is available from the Xbox 360 dashboard in the regions of Canada, France, Italy, Spain, United Kingdom and the United States. Alternatively, you can visit the &lt;a href="http://marketplace.xbox.com/en-US/games/media/66acd000-77fe-1000-9115-d802585501d3/?p=1&amp;of=0&amp;sb=1"&gt;Xbox 360 marketplace website&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/nextwar_x360.html"&gt;Micron Game Studios Website Link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1266156532536618875?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1266156532536618875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1266156532536618875' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1266156532536618875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1266156532536618875'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/03/nextwar-quest-for-earth-released-for.html' title='NextWar: The Quest for Earth released for the Xbox 360!'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1826082699516315087</id><published>2009-03-17T13:34:00.004+11:00</published><updated>2009-03-17T13:40:01.887+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: Coming Soon to Xbox Live</title><content type='html'>&lt;a href="http://www.youtube.com/watch?v=Q7sc2yV2cis&amp;fmt=22"&gt;NextWar: The Quest for Earth Xbox 360 Trailer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/files/nextwar_x360/NextWar_Trailer_Xbox360.wmv"&gt;High Resolution Download&lt;/a&gt; (46.9mb, right-click save-as)&lt;br /&gt;&lt;br /&gt;Coming soon to Xbox Live Community Games.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1826082699516315087?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1826082699516315087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1826082699516315087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1826082699516315087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1826082699516315087'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/03/nextwar-coming-soon-to-xbox-live.html' title='NextWar: Coming Soon to Xbox Live'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4772282933274731632</id><published>2009-03-05T11:33:00.002+11:00</published><updated>2009-03-05T11:34:14.462+11:00</updated><title type='text'>Melbourne Uni</title><content type='html'>The UniWireless wireless network sucks. Everything must go through a proxy. Can't SSH, can't telnet, can't rdesktop, can't access my Perforce server at home.&lt;br /&gt;&lt;br /&gt;At least HTTP works just fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4772282933274731632?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4772282933274731632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4772282933274731632' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4772282933274731632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4772282933274731632'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2009/03/melbourne-uni.html' title='Melbourne Uni'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7308874722610891109</id><published>2008-12-29T21:55:00.001+11:00</published><updated>2008-12-29T21:57:04.134+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar on the Xbox 360?</title><content type='html'>I'm going to go hide in my little cave and tinker away with my programming for a while.&lt;br /&gt;&lt;br /&gt;When I emerge, maybe there will be a new tower defense game available on Xbox Live.&lt;br /&gt;&lt;br /&gt;If I don't give up before then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7308874722610891109?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7308874722610891109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7308874722610891109' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7308874722610891109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7308874722610891109'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/12/nextwar-on-xbox-360.html' title='NextWar on the Xbox 360?'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2654776093584878440</id><published>2008-12-15T08:30:00.004+11:00</published><updated>2008-12-15T08:37:18.167+11:00</updated><title type='text'>VCE Results</title><content type='html'>ENTER: 97.70&lt;br /&gt;&lt;br /&gt;Raw subject scores:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;CH03 - Chemistry&lt;br /&gt;   GA 1:  B+&lt;br /&gt;   GA 2:  A+&lt;br /&gt;   GA 3:  A+&lt;br /&gt;   Study Score: 38&lt;br /&gt;   &lt;br /&gt;EN01 - English&lt;br /&gt;   GA 1:  A&lt;br /&gt;   GA 2:  A&lt;br /&gt;   GA 3:  B+&lt;br /&gt;   Study Score: 34&lt;br /&gt;   &lt;br /&gt;MA08 - Mathematical Methods&lt;br /&gt;   GA 1:  A+&lt;br /&gt;   GA 2:  A+&lt;br /&gt;   GA 3:  A+&lt;br /&gt;   Study Score: 45&lt;br /&gt;   &lt;br /&gt;MA09 - Specialist Mathematics&lt;br /&gt;   GA 1:  A+&lt;br /&gt;   GA 2:  A&lt;br /&gt;   GA 3:  A+&lt;br /&gt;   Study Score: 40&lt;br /&gt;   &lt;br /&gt;PH03 - Physics&lt;br /&gt;   GA 1:  A+&lt;br /&gt;   GA 2:  A+&lt;br /&gt;   GA 3:  A+&lt;br /&gt;   Study Score: 46&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;Scaled Study Scores:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;English:                                32.48&lt;br /&gt;Specialist Mathematics:                 47.91&lt;br /&gt;Mathematical Methods:                   47.89&lt;br /&gt;Physics:                                47.75&lt;br /&gt;Chemistry:                              42.67&lt;br /&gt;Info Tech: Software Development (2007): 39.71&lt;br /&gt;Aggregate: 184.2&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I did well enough. My first preference, Bachelor of Science at The University of Melbourne, requires an ENTER score of only 85.00. Party time?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2654776093584878440?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2654776093584878440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2654776093584878440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2654776093584878440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2654776093584878440'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/12/vce-results.html' title='VCE Results'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4438241630241753077</id><published>2008-12-12T12:10:00.004+11:00</published><updated>2008-12-12T12:15:38.300+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><category scheme='http://www.blogger.com/atom/ns#' term='LOLCODE'/><title type='text'>LOLExec: A Dynamic LOLCODE Interpreter</title><content type='html'>Well, today I released version 1.0 of LOLExec. LOLExec is an interpreter for the esoteric programming language &lt;a href="http://lolcode.com/"&gt;LOLCODE&lt;/a&gt;. For example, here's the &lt;a href="http://en.wikipedia.org/wiki/Hello_World"&gt;Hello World&lt;/a&gt; program:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;HAI&lt;br /&gt;CAN HAS STDIO?&lt;br /&gt;VISIBLE "HAI WORLD!"&lt;br /&gt;KTHXBYE&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I've put it up for download here:&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/lolexec.html"&gt;http://www.microngamestudios.com/lolexec.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the binary executable package, I've included a few sample applications along with the interpreter: for example a prime number finder and a few solutions to &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; problems implemented in LOLCODE. Also available is a large suite of unit tests that I wrote during the course of development. Feel free to use them as you wish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4438241630241753077?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4438241630241753077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4438241630241753077' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4438241630241753077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4438241630241753077'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/12/lolexec-dynamic-lolcode-interpreter.html' title='LOLExec: A Dynamic LOLCODE Interpreter'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8627052340497064916</id><published>2008-12-05T19:31:00.004+11:00</published><updated>2008-12-05T20:12:55.668+11:00</updated><title type='text'>Finishing school</title><content type='html'>So on wednesday evening, Melbourne High School had its annual Speech Night event at Hisense Arena (formerly Vodafone Arena) in central Melbourne. It was effectively a graduation ceremony for us year 12's, and marked the end of our time at MHS.&lt;br /&gt;&lt;br /&gt;My 4 year journey through MHS has certainly been memorable, and I am certain that I'll not forget it. I sure enjoyed my time there and, as cliche as it sounds, I'm sad that my time there has now come to an end.&lt;br /&gt;&lt;br /&gt;That said, I am proud to be able to call myself an Old Boy of Melbourne High School. Now all that's left is to eagerly await the announcement of the VCE results on December 15th.&lt;br /&gt;&lt;br /&gt;I sleep now. Valedictory dinner last night, "slept" over at a friend's house afterwards, played Halo 3 and talked all night instead of sleeping. ^_^&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8627052340497064916?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8627052340497064916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8627052340497064916' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8627052340497064916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8627052340497064916'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/12/finishing-school.html' title='Finishing school'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8421789796694722774</id><published>2008-11-14T17:52:00.002+11:00</published><updated>2008-11-14T17:57:28.526+11:00</updated><title type='text'>eGames Expo</title><content type='html'>So I was at the &lt;a href="http://www.idef.com.au/egames_home.php"&gt;eGames Expo&lt;/a&gt; today at the Melbourne Exhibition Centre. I played games, shook hands with &lt;a href="http://en.wikipedia.org/wiki/Ben_Croshaw"&gt;Yahtzee&lt;/a&gt;, and recieved an 8GB 4th-Gen iPod Nano from Monash University.&lt;br /&gt;&lt;br /&gt;Was a fun day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8421789796694722774?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8421789796694722774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8421789796694722774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8421789796694722774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8421789796694722774'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/11/egames-expo.html' title='eGames Expo'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1054861989816453593</id><published>2008-10-22T15:50:00.002+11:00</published><updated>2008-10-22T15:55:02.463+11:00</updated><title type='text'>Rickrolling the school</title><content type='html'>So today I rickrolled the entire school as a final prank. A little bit of internet-inspired idiocy to break up an otherwise bland day. :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=PbACIVJXsTA"&gt;http://www.youtube.com/watch?v=PbACIVJXsTA&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1054861989816453593?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1054861989816453593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1054861989816453593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1054861989816453593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1054861989816453593'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/10/rickrolling-school.html' title='Rickrolling the school'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1570340368749596638</id><published>2008-10-20T20:10:00.004+11:00</published><updated>2008-10-20T20:34:53.288+11:00</updated><title type='text'>XKCD Everywhere</title><content type='html'>So today is final week for Year 12's at &lt;a href="http://en.wikipedia.org/wiki/Melbourne_High_School"&gt;MHS&lt;/a&gt;. I have no idea when &lt;a href="http://en.wikipedia.org/wiki/Muck-up_day"&gt;muck-up day&lt;/a&gt; actually is, so I've just referred to this entire week as "muck-up week".&lt;br /&gt;&lt;br /&gt;Since I'm in Year 12 and this is our last year, a few friends and I thought we might leave a little bit of a parting gift for our comrades at school. Fans of &lt;a href="http://www.xkcd.com/"&gt;XKCD&lt;/a&gt; that we were, what better way to spend our mischief than to spread the word of XKCD?&lt;br /&gt;&lt;br /&gt;So we did. Over a weekend, I printed out 400 different XKCD comics. 5 times. 2000 odd sheets of paper bundled up and brought to school today in the wee hours of the morning.&lt;br /&gt;&lt;br /&gt;Even though we started at about 6:30AM, we still had at least 500 comics left to tape up by the time the form assembly bell went at about 8:50AM. But by that time, a good portion of the 20's castle building was already plastered in XKCD. We put up the rest of them later in the day.&lt;br /&gt;&lt;br /&gt;Total cost: about $100. $20 for paper, $45 for toner, the rest for a heck of a lot of expensive tape. We couldn't use regular tape on the walls because it would peel the paint off - so I had to buy magic tape for $5 a roll (stupid 3M has a monopoly on the adhesives market). It was a waste of money, some would say. I beg to differ. Bringing the word of XKCD to the masses is a very worthwhile use of money. Besides, I recently came into &lt;a href="http://adtsai.blogspot.com/2008/08/swingame-08-competition-results.html"&gt;$3000&lt;/a&gt; in cash... gotta use it for something!&lt;br /&gt;&lt;br /&gt;I wonder how long these comics will stay up there (and who's going to clean this mess up?)&lt;br /&gt;&lt;br /&gt;Preparation - the stacks of XKCD:&lt;br /&gt;&lt;a href="http://img362.imageshack.us/img362/5571/dsc04935in9.jpg"&gt;&lt;img src="http://img362.imageshack.us/img362/5571/dsc04935in9.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The front of the unsuspecting school at 6:20 AM:&lt;br /&gt;&lt;a href="http://img505.imageshack.us/img505/8734/dsc04943cn8.jpg"&gt;&lt;img src="http://img505.imageshack.us/img505/8734/dsc04943cn8.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Maths department:&lt;br /&gt;&lt;a href="http://img257.imageshack.us/img257/2672/dsc04965vu4.jpg"&gt;&lt;img src="http://img257.imageshack.us/img257/2672/dsc04965vu4.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img516.imageshack.us/img516/2486/dsc04966mw6.jpg"&gt;&lt;img src="http://img516.imageshack.us/img516/2486/dsc04966mw6.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img362.imageshack.us/img362/1851/dsc04952ok7.jpg"&gt;&lt;img src="http://img362.imageshack.us/img362/1851/dsc04952ok7.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img505.imageshack.us/img505/6078/dsc04950fr2.jpg"&gt;&lt;img src="http://img505.imageshack.us/img505/6078/dsc04950fr2.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Science department:&lt;br /&gt;&lt;a href="http://img362.imageshack.us/img362/3669/dsc04958dw7.jpg"&gt;&lt;img src="http://img362.imageshack.us/img362/3669/dsc04958dw7.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img384.imageshack.us/img384/4239/dsc04957hd4.jpg"&gt;&lt;img src="http://img384.imageshack.us/img384/4239/dsc04957hd4.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dining hall:&lt;br /&gt;&lt;a href="http://img266.imageshack.us/img266/2051/dsc04956wb6.jpg"&gt;&lt;img src="http://img266.imageshack.us/img266/2051/dsc04956wb6.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img516.imageshack.us/img516/8573/dsc04955lz3.jpg"&gt;&lt;img src="http://img516.imageshack.us/img516/8573/dsc04955lz3.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;  &lt;a href="http://img257.imageshack.us/img257/307/dsc04954ne4.jpg"&gt;&lt;img src="http://img257.imageshack.us/img257/307/dsc04954ne4.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hallways/stairwells:&lt;br /&gt;&lt;a href="http://img362.imageshack.us/img362/2856/dsc04964vw6.jpg"&gt;&lt;img src="http://img362.imageshack.us/img362/2856/dsc04964vw6.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img505.imageshack.us/img505/3246/dsc04963hb2.jpg"&gt;&lt;img src="http://img505.imageshack.us/img505/3246/dsc04963hb2.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img516.imageshack.us/img516/6726/dsc04961lo9.jpg"&gt;&lt;img src="http://img516.imageshack.us/img516/6726/dsc04961lo9.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://img505.imageshack.us/img505/9154/dsc04960qv9.jpg"&gt;&lt;img src="http://img505.imageshack.us/img505/9154/dsc04960qv9.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;On a completely unrelated note, I happened to have my camera handy while the teacher dunking was happening:&lt;br /&gt;&lt;a href="http://img266.imageshack.us/img266/7513/dsc04972cp9.jpg"&gt;&lt;img src="http://img266.imageshack.us/img266/7513/dsc04972cp9.th.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1570340368749596638?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1570340368749596638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1570340368749596638' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1570340368749596638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1570340368749596638'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/10/xkcd-everywhere.html' title='XKCD Everywhere'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-815047645253948017</id><published>2008-09-17T17:35:00.002+10:00</published><updated>2008-09-17T17:37:25.441+10:00</updated><title type='text'>Art of Defence Download</title><content type='html'>Just like with NextWar, I've put up Art of Defence for free download. You can get it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/aod.html"&gt;http://www.microngamestudios.com/aod.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-815047645253948017?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/815047645253948017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=815047645253948017' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/815047645253948017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/815047645253948017'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/09/art-of-defence-download.html' title='Art of Defence Download'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8965363942938899252</id><published>2008-09-16T22:15:00.005+10:00</published><updated>2008-09-18T15:01:44.459+10:00</updated><title type='text'>Monash IT Challenge 2008 Result</title><content type='html'>I guess I'm on a roll. :D&lt;br /&gt;&lt;br /&gt;About a month ago, I submitted a tower defence game called "Art of Defence" to Monash University to compete in their &lt;a href="http://www.infotech.monash.edu.au/promotion/competitions/it-challenge/"&gt;IT Challenge 2008 Competition&lt;/a&gt;. Today, at the BMW Edge Cinema at Federation Square, Monash held a prize ceremony for this competition. Art of Defence won first place in the Games Development category.&lt;br /&gt;&lt;br /&gt;To be honest, I was surprised to win this competition - I had no idea the game would do so well. I wrote the core code for the game back in 2006, when I was in Year 10 (and just having completed Game Design as an elective at school). Art of Defence was written in C++, using DirectX 9.0. Sometime later on, I'll host it on &lt;a href="http://www.microngamestudios.com/"&gt;microngamestudios.com&lt;/a&gt; for free download, just like I did for NextWar.&lt;br /&gt;&lt;br /&gt;I'm not actually sure what the first prize is, but rumour has it that it's a new iPod Nano*. According to Monash, they're having some supply issues so it'll be a few weeks until I get the prize.&lt;br /&gt;&lt;br /&gt;Once again, thanks to Mr. Adrian Janson for sponsoring me in the competition, and to the faculty of IT at Monash and to Andrew Owen for their work in setting up the competition. And congratulations to Alan Lahiff, too, who was the other Melbourne High prize winner. He won prizes in the Programming and Database categories, and came second in the running for the IT Challenge Student of the Year. He won a heck of a lot of stuff, so hats off to him!&lt;br /&gt;&lt;br /&gt;Anyway, here's a photo of the trophy:&lt;br /&gt;&lt;center&gt;&lt;a href="http://img523.imageshack.us/img523/1697/trophyqd1.jpg"&gt;&lt;img src="http://img523.imageshack.us/img523/1697/trophyqd1.th.jpg" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The text reads:&lt;br /&gt;&lt;center&gt;&lt;i&gt;IT Challenge 2008&lt;br /&gt;Category&lt;br /&gt;Game Development&lt;br /&gt;&lt;br /&gt;1st Place&lt;br /&gt;Adrian Tsai&lt;br /&gt;Melbourne High&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* EDIT: I've just recieved an email from Andrew Owen about the prize - first prize in my category recieves a brand new 4GB iPod Nano! According to &lt;a href="http://en.wikipedia.org/wiki/Ipod_nano#Models"&gt;Wikipedia&lt;/a&gt;, I guess that would make it a 4th Gen iPod Nano. I'll also be getting free tickets to IDEF, the &lt;a href="http://www.idef.com.au/"&gt;International Digital Entertainment Festival&lt;/a&gt;, which will be on during the 14th-16th November. Can't wait!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8965363942938899252?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8965363942938899252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8965363942938899252' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8965363942938899252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8965363942938899252'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/09/monash-it-challenge-2008-result.html' title='Monash IT Challenge 2008 Result'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-6400748790467064827</id><published>2008-09-11T18:50:00.003+10:00</published><updated>2008-09-11T18:56:16.756+10:00</updated><title type='text'>DMC4 HD Cutscenes For Download</title><content type='html'>So I was crazy (or stupid) enough to record, encode and host all the cutscenes from Devil May Cry 4 in HD resolution (1280x720).&lt;br /&gt;&lt;br /&gt;I've put them up for download here:&lt;br /&gt;&lt;a href=http://www.microngamestudios.com/dmc4.html&gt;http://www.microngamestudios.com/dmc4.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When added all up, the cutscenes are 1:57:30 long, and approx. 5.2GB. They were recorded from the PC version of the game, with all settings on maximum except for shadows (as the super-high shadow setting is buggy). C8xAA was also turned on for all cutscenes.&lt;br /&gt;&lt;br /&gt;I love this game so much. :D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-6400748790467064827?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/6400748790467064827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=6400748790467064827' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6400748790467064827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6400748790467064827'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/09/dmc4-hd-cutscenes-for-download.html' title='DMC4 HD Cutscenes For Download'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7959194024176108565</id><published>2008-08-23T22:03:00.004+10:00</published><updated>2008-08-23T22:07:05.848+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Download</title><content type='html'>I've put up NextWar for download. You can get it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/nextwar.html"&gt;http://www.microngamestudios.com/nextwar.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Excuse the horrendous site layout, it's still under construction (and I'm a programmer, not a web artist). :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7959194024176108565?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7959194024176108565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7959194024176108565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7959194024176108565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7959194024176108565'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/08/nextwar-download.html' title='NextWar Download'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8471019666355470010</id><published>2008-08-17T19:07:00.004+10:00</published><updated>2008-08-17T19:59:48.057+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>SwinGame 08 Competition Results</title><content type='html'>And so ends the SwinGame 08 Game Design Competition. Today, at Swinburne's Hawthorn campus, the results for the competition were announced.&lt;br /&gt;&lt;br /&gt;NextWar won first place and I recieved a certificate, a trophy, and a prize of $3000.&lt;br /&gt;&lt;br /&gt;NextWar was the result of many months of hard work. I started on NextWar in March, and since then I worked on it almost continuously during my free time. Between school and studying, I devoted what time I could to my pet project. Even though NextWar turned out to be something different to what I had originally intended, and despite a number of small setbacks, I managed to finish and polish NextWar.&lt;br /&gt;&lt;br /&gt;There some people I would like to thank: Mr. Adrian Janson, my IT teacher at Melbourne High; my beta testers (Geoff Hong, Julian Taylor, Geoff Wong, Callum Young), who helped me perform balance testing, bug-hunting, and suggested feedback; and finally the SwinGame team as well as the staff and students of Swinburne for creating an awesome game engine and allowing me to create NextWar!&lt;br /&gt;&lt;br /&gt;Congratulations to the other prize winners, I hope you all had as much fun as I did.&lt;br /&gt;&lt;br /&gt;Over the next week or so, I'll release NextWar publicly for free so that anyone can play it if they so wish. I'll also release the source code as required by the GNU GPL (which SwinGame is licensed under).&lt;br /&gt;&lt;br /&gt;The certificate:&lt;br /&gt;&lt;center&gt;&lt;a href="http://img179.imageshack.us/img179/4985/certificatemk8.jpg"&gt;&lt;img src="http://img179.imageshack.us/img179/4985/certificatemk8.th.jpg" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;And yes, that's a misprint. It's supposed to say &lt;span&gt;17 August &lt;span style="font-weight: bold;"&gt;2008&lt;/span&gt;&lt;/span&gt;, not 17 August &lt;span style="font-weight: bold;"&gt;2007&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The trophy:&lt;br /&gt;&lt;center&gt;&lt;a href="http://img242.imageshack.us/img242/3959/trophyrh9.jpg"&gt;&lt;img src="http://img242.imageshack.us/img242/3959/trophyrh9.th.jpg" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;The inscription reads:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;SwinGame 08&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Computer Game Design&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Competition&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;1st Prize&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Team - Micron Game Studios&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8471019666355470010?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8471019666355470010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8471019666355470010' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8471019666355470010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8471019666355470010'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/08/swingame-08-competition-results.html' title='SwinGame 08 Competition Results'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2284975203078212801</id><published>2008-07-08T14:36:00.004+10:00</published><updated>2008-07-09T14:03:00.848+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Progress</title><content type='html'>After a month-long hiatus from development to focus on exams, I got right back into it a couple of weeks ago. Since the beginning of the holidays, I've been working practically exclusively on NextWar, and great changes have come about.&lt;br /&gt;&lt;br /&gt;I had a mid-project change of heart and decided to rethink my concepts for NextWar. After losing a month of development time to school, it was unlikely that I would be able to complete my ambitious plans for NextWar. So I made the decision to reduce the size and scope of the project.&lt;br /&gt;&lt;br /&gt;NextWar is no longer an RTS. It will still incorporate a few concepts due to its RTS-based beginnings, but it has switched genres entirely. I'd always been a fan of small time-waster flash games, and one of my favourites was inevitably the &lt;a href="http://en.wikipedia.org/wiki/Tower_Defense"&gt;Tower Defense&lt;/a&gt; genre. I still remember playing the old TD secret mission in Warcraft III - and how much fun it was. And I remember wasting time playing &lt;a href="http://www.novelconcepts.co.uk/FlashElementTD/"&gt;Flash Element TD&lt;/a&gt; at 1AM when I should have been doing my school work due the next day. So, at the beginning of the holidays, I made the decision to turn NextWar into a Tower Defense game.&lt;br /&gt;&lt;br /&gt;I was at an odd crossroads. A few weeks ago, I had the framework for a game, including a fully-fledged renderer, GUI systems, sound, XML, etc. And very little code was specific to an RTS. So in the end, I never threw away very much code. There's still a lot of old bits and pieces of legacy and deprecated code throughout my codebase, but little effort overall has been wasted.&lt;br /&gt;&lt;br /&gt;But the simplicity of a tower defense game in comparison to a fully-fledged RTS has allowed me to fast-track development of the game. NextWar's development cycle is now drawing to a close, as the game's core code is effectively finished after only 2 weeks of development. Now I enter the heady realm of final content creation, testing, evaluation, and bug-fixing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2284975203078212801?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2284975203078212801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2284975203078212801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2284975203078212801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2284975203078212801'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/07/nextwar-progress.html' title='NextWar Progress'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8469136016603413778</id><published>2008-07-08T10:13:00.002+10:00</published><updated>2008-09-26T09:16:22.453+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar Trailer</title><content type='html'>I was bored.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microngamestudios.com/files/nextwar/NextWar_Trailer.wmv"&gt;NextWar: The Quest for Earth - Teaser Trailer (right-click, save-as, 41mb)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8469136016603413778?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8469136016603413778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8469136016603413778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8469136016603413778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8469136016603413778'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/07/nextwar-trailer.html' title='NextWar Trailer'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3481390901589734915</id><published>2008-05-06T22:11:00.002+10:00</published><updated>2008-05-06T22:16:46.107+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>Building the map generator</title><content type='html'>Progress on NextWar has been steady. I've just completed my mapping algorithms and related code. NextWar will use a simple tile-based system, like almost every other RTS out there. Because NextWar will be based primarily on vector graphics, it may appear odd that I've chosen tile-based for my game. There are real logical and practical reasons for this, though. Tile-based systems have the advantage of being time efficient - at the expense of space (memory). In particular, I had concerns over pathfinding - how would units pathfind through a vector maze? I've only had experience with tile-based pathfinding before, and I've written good heuristic pathfinders before based on existing well-known algorithms. But I've never seen or heard of a vector pathfinding system in any real RTS game. While vector-based systems would allow for much more flexibility, it's also very limited in its practical applications. It really reminds me of arguments of vector graphics vs. rasterised graphics. Vector graphics are extensible and flexible, but slow and sometimes hard to use. That's why I chose to use good old tiles.&lt;br /&gt;&lt;br /&gt;So far, I've defined a couple of basic map tiles: grass, dirt, concrete, water, and sand. Like almost everything else in the game, maps are defined through XML files, and can be very easily modified. There are actually no art assets for each tile type - the graphics for each tile are procedurally generated at map load time using custom algorithms. This saves on art costs, ensures that no repetitiveness is seen in the tiles on the map, and spares the world from some of my terrible art skills. I considered adding the functionality of a heightmap to the game, but it was quickly rejected. Being a 2D top-down RTS, it would be difficult to correctly display a real 3D heightmapped map, and as such the player wouldn't even be able to tell differences in terrain height. This is exacerbated by the fact that I'm limiting myself to using vector art for stylistic reasons. In addition, it would complicate gameplay, which is something I'm striving to avoid.&lt;br /&gt;&lt;br /&gt;In any RTS you play, you'll find that map tiles and edges are never sharply defined. Instead, they are always blended together and the transition between texture types is always smooth. This is usually done using a technique called &lt;a href=http://www.gamedev.net/reference/articles/article2238.asp&gt;texture splatting&lt;/a&gt;. However, since all my art is vector graphics, this generally isn't possible. My first mapping attempt resulted, expectedly, in a whole bunch of really visible "blocks" due to the low granularity of the tiles. The solution?&lt;br /&gt;&lt;br /&gt;I wrote a smoothing algorithm to automatically round off the sharp corners of the tiles, while at the same time providing an outline surrounding each tile type to make it easier to clearly differentiate between tile types.&lt;br /&gt;&lt;br /&gt;This is what it looked like before: (using &lt;strong&gt;preliminary test art&lt;/strong&gt;)&lt;br /&gt;&lt;center&gt;&lt;a href=http://img123.imageshack.us/img123/7214/map0zd9.png&gt;&lt;img src=http://img123.imageshack.us/img123/7214/map0zd9.th.png /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;And after, in approximately the same location:&lt;br /&gt;&lt;center&gt;&lt;a href=http://img84.imageshack.us/img84/7154/map1gk3.png&gt;&lt;img src=http://img84.imageshack.us/img84/7154/map1gk3.th.png /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the previously sharp corners have been rounded off. In addition, the algorithm accounts for the "cut out" corners, and clips vertices and primitives as required. But as this would leave unsightly gaps in the tiles at the corners, the algorithm also &lt;i&gt;fills in&lt;/i&gt; the gaps with the correct tile graphics (which, of course, is all procedurally generated). There were a lot of corner cases in implementing the algorithm (pun intended). For example, points where 3 or 4 tiles could meet needed to be handled separately since the default algorithm simply didn't look good for those cases. Things like map edges, overlapping tile graphics, etc. needed to be handled as well.&lt;br /&gt;&lt;br /&gt;Another problem I ran into was that the procedural generation and culling left a lot of unused (orphaned) vertices lying about, and a lot of duplicate vertices which resided in the same place. Removal of orphans was simple, it was just a matter of looping through all the indices and deleting the vertices which were unindexed by the index buffer. But when it came to removing duplicate vertices, I came back to my old friend: the vertex welder. Having had &lt;a href=http://adtsai.blogspot.com/2008/04/optimising-vertex-welder-adventures.html&gt;previously written&lt;/a&gt; a fast, spatially-partitioned vertex welder for DirectX10 in the past, I'm familiar with the techniques required to "weld" similar vertices together (which eliminates duplicates, saving both memory and time).&lt;br /&gt;&lt;br /&gt;However, the techniques I employed in my original C++, DX10 welder were designed for meshes in the range of ~100,000 polygons. Because, at worst, the time complexity for welding could get as bad as O(n^3), I had to use an octree to spatially partition the data into more manageable chunks, and apply the standard O(n^2) algorithm on it. I realised, that with only a few thousand vertices in my map mesh, even a slow brute-force O(n^2) method would likely be fast enough. In a few minutes, I wrote the vertex welder and a quick profile revealed that the vertex welder ran over the entire map mesh in about 10-20ms. This was more than fast enough, and I didn't bother optimising it further (remember, kids, premature optimisation is the root of all evil!).&lt;br /&gt;&lt;br /&gt;Now that I've got the mapping algorithms done, I can begin on improving the procedural algorithms to produce some better looking vector art. Since I'm using procedural generation at load time, I can guarantee that no two tiles will look the same if I don't want them to. And, it also means that I can quickly and easily modify the look of entire maps by tweaking a few parameters in code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3481390901589734915?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3481390901589734915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3481390901589734915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3481390901589734915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3481390901589734915'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/05/building-map-generator.html' title='Building the map generator'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-6432243728963682615</id><published>2008-04-27T13:00:00.000+10:00</published><updated>2008-04-27T13:01:01.997+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar - Campaign</title><content type='html'>Campaign layout ideas.&lt;br /&gt;&lt;br /&gt;&lt;a href=http://members.iinet.net.au/~mcf1/NextWar/Design%20-%20Campaign.pdf&gt;Design - Campaign.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-6432243728963682615?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/6432243728963682615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=6432243728963682615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6432243728963682615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6432243728963682615'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/nextwar-campaign.html' title='NextWar - Campaign'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-5071137570626859823</id><published>2008-04-26T10:01:00.002+10:00</published><updated>2008-04-26T10:07:28.793+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar - Faction Design</title><content type='html'>A very preliminary document outlining some of the units, structures and upgrades available to each faction. It's probably going to be changed a lot once I actually get the game done and the factions need to be balanced.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://members.iinet.net.au/~mcf1/NextWar/Design%20-%20Factions.pdf"&gt;Design - Factions.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-5071137570626859823?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/5071137570626859823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=5071137570626859823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5071137570626859823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/5071137570626859823'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/nextwar-faction-design.html' title='NextWar - Faction Design'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-390877989525982758</id><published>2008-04-25T09:25:00.002+10:00</published><updated>2008-04-25T09:53:14.449+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar - Plot Outline</title><content type='html'>Next up is a summary of the plot and backstory behind each faction.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://members.iinet.net.au/~mcf1/NextWar/Design%20-%20Plot%20Outline.pdf"&gt;NextWar: The Quest for Earth&lt;br /&gt;Design - Plot Outline.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-390877989525982758?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/390877989525982758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=390877989525982758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/390877989525982758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/390877989525982758'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/nextwar-plot-outline.html' title='NextWar - Plot Outline'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-959141434139367348</id><published>2008-04-24T19:17:00.003+10:00</published><updated>2008-04-24T19:43:20.545+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><category scheme='http://www.blogger.com/atom/ns#' term='Optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Optimising the NextWar loader - why Xml.Serialization is so slow</title><content type='html'>One of the core design goals of NextWar is that it should function much like a casual game. That means that it needs to satisfy a some criteria for what a user should expect from a casual game. One of these criteria is that it must start and load quickly. Long load times prohibit the "just start and play" factor that you should be able to expect from a casual game.&lt;br /&gt;&lt;br /&gt;This was a problem I initially encountered with NextWar. NextWar was designed to be incredibly data-driven. One of the earliest design choices I made was to use an XML-based content definition system for definition practically every aspect of the game. XML-based approaches have been very successful in other games, such as &lt;i&gt;Command and Conquer 3&lt;/i&gt; and &lt;i&gt;Civilization 4&lt;/i&gt;. XML is particularly convenient for me because I'm using C# - and as such have access to the massive .NET BCL. One of the most useful set of classes I've found were in Xml.Serialization. Xml.Serialization has the ability to automatically load an XML file and deserialise it into a user-defined class. It also operates in reverse; it can serialise any user type into an XML format. This is useful for things like settings and save games.&lt;br /&gt;&lt;br /&gt;When I wrote SCALE, one of the major challenges I faced was this same issue of deserialisation - once I got the data from the file, how did I get it into the data structure? C++ has no automated facilities for this - in the end I resorted to an incredibly long and verbose manual method of copying raw data into specified data members.&lt;br /&gt;&lt;br /&gt;Using the power of bytecode, .NET is able to automate the entire process. Seriously, deserialising an XML file takes about 10 lines of code. But, like all things, there is a price to pay for this convenience. Even though I have a very small amount of data (currently about 125KB of XML data), parsing and deserialisation took about 4.5 seconds on a relatively high end 2.8ghz Core 2 Duo. This was insanity - and I knew in advance that I was going to have a LOT more than 125kb of XML by the time I finished the game. The problem was also that all the time was spent in the core .NET libraries themselves - profiling revealed that my code was lightning-fast. The culprit was, unexpectedly enough, Xml.Serialization.&lt;br /&gt;&lt;br /&gt;After a lot of in-depth research into the issue, what makes Xml.Serialization so damn slow? The main reason has nothing to do with data conversions, or parsing, or anything like that. The reason is that Xml.Serialization needs to go through a long (and extremely expensive) process to generate the necessary metadata to load the data into your class.&lt;br /&gt;&lt;br /&gt;Here's what Xml.Serialization does. It uses the .NET reflection libraries (which, by themselves, are already &lt;i&gt;incredibly&lt;/i&gt; slow) to look into the assembly bytecode for the class that you're trying to deserialise. Then, it generates new bytecode from this class so that it can serialise/deserialise each of the data members. In short, it generates a serialiser or deserialiser class &lt;i&gt;on the fly&lt;/i&gt;. Once it generates the bytecode for the class, it then compiles that bytecode into a DLL assembly, which is then loaded by the .NET runtime. The .NET JIT&lt;sup&gt;1&lt;/sup&gt; (just-in-time) compiler then compiles this code and executes it.&lt;br /&gt;&lt;br /&gt;All of this is, understandably, &lt;b&gt;extremely&lt;/b&gt; slow. Generating an assembly like this could take hundreds of milliseconds for each type. And I know that Xml.Serialization is actually doing this; the Visual Studio debugger confirmed it. But what to do about it?&lt;br /&gt;&lt;br /&gt;Well, as it turns out, Microsoft provides a tool with the Visual Studio SDK called SGEN. SGEN does exactly what Xml.Serialization does - except that instead of loading and using the generated DLL, it saves it to file. Thus, it is a tool to pre-generate the serialisers/deserialisers into a DLL which can then be loaded and used directly, rather than letting Xml.Serialization do it &lt;i&gt;at load time&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;After a bit of fiddling, I got SGEN to work, and I linked my program against it to use the deserialisers. And lo and behold, my load time was cut in half. Deserialising XML files is now lighting fast, thanks to this handy little tool.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt;  It's a common misconception that .NET code is bytecode-interpreted. Such a thing might be fine for a simple scripting language, but would be far too slow for something like .NET. Rather, the .NET runtime includes a Just-In-Time compiler (often referred to as the "JIT"). When the program loads, the JIT reads the bytecode and dynamically compiles it into native assembly instructions. Then, this native assembly is executed directly by the CPU. The nature of the JIT, and the fact that it needs to be done at runtime, means that the assembly code will be nowhere near as fast as an off-line optimising C++ compiler, for example. The JIT is designed to run fast, but it's still not a good idea to be invoking it unless really needed. And in this case of Xml.Serialization, it was certainly not needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-959141434139367348?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/959141434139367348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=959141434139367348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/959141434139367348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/959141434139367348'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/optimising-nextwar-loader-why.html' title='Optimising the NextWar loader - why Xml.Serialization is so slow'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-2929706502865776262</id><published>2008-04-18T17:38:00.003+10:00</published><updated>2008-04-24T19:15:49.198+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NextWar'/><title type='text'>NextWar: The Quest for Earth</title><content type='html'>"NextWar" is such a nice generic name, isn't it?&lt;br /&gt;&lt;br /&gt;Well, it's pretty much official now. I've joined the &lt;a href="http://www.swingame.com/"&gt;SwinGame&lt;/a&gt; game competition.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SwinGame&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SwinGame is an API written by the staff and students of Swinburne University, based here in Melbourne, Australia. Swinburne is also backing the SwinGame 08 Competition - where Australian Year 11 and Year 12 students can participate in a competition to create the best overall game using the SwinGame API.&lt;br /&gt;&lt;br /&gt;The grand prize is $3000 for the author of the game. Second prize is $2000 and third prize is $1000.&lt;br /&gt;&lt;br /&gt;Since I happen to be an Australian student currently studying in Year 12, I'm entering this contest. Hopefully, come August this year, I'll be walking away with $3000.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;NextWar&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;NextWar is what I decided to name my game. It came to me while sitting on the train, which is where I also formulated the basic game mechanics and plot structure. NextWar's full name is "NextWar: The Quest for Earth". It's going to be a 2D RTS game, written in C# and using the SwinGame API.&lt;br /&gt;&lt;br /&gt;For more information, I'll be posting progress reports &lt;a href=http://www.swingame.com/swinforum/viewtopic.php?f=8&amp;t=31&gt;here&lt;/a&gt;, as well as here to this blog.&lt;br /&gt;&lt;br /&gt;So far, I've got the basic framework for the game done; gamestate management and GUI are all complete, as well as the asset loading system and basic renderer.&lt;br /&gt;&lt;br /&gt;Also, I've been doing some design for the actual game itself. I've been writing some documents for my own personal use regarding the design of the game. I decided to post them here; they're not very interesting and not particularly well done, but they function as an effective brain-dump for ideas. And it couldn't hurt to post them online. I never intended for them to be seen by anyone other than me, so sorry if they don't make much sense.&lt;br /&gt;&lt;br /&gt;So, without further ado, the first in a series of documents I'll be posting:&lt;br /&gt;&lt;br /&gt;&lt;a href=http://www.swingame.com/swinforum/download/file.php?id=5&gt;NextWar: The Quest for Earth&lt;br /&gt;Design - Basic Overview &amp; Gameplay&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-2929706502865776262?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/2929706502865776262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=2929706502865776262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2929706502865776262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/2929706502865776262'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/nextwar-quest-for-earth.html' title='NextWar: The Quest for Earth'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8385844292068407786</id><published>2008-04-03T17:46:00.008+11:00</published><updated>2008-04-24T19:17:44.457+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Optimising the Vertex Welder: Adventures Into Spatial Partitioning</title><content type='html'>Vertex welding is simply an optimisation technique to reduce the number of vertices sent to the graphics hardware. It's very simple: if there there are two vertices which are very close to each other, then the two vertices are "welded" into a single vertex. Since the vertices were so close together in the first place, nobody ever notices and we just saved ourselves a vertex.&lt;br /&gt;&lt;br /&gt;Really, vertex welding is just a specialised form of collision detection. Each vertex needs to be checked against every other vertex to see if they're close together or not (and welded if they are). As such, a naive implementation runs in O(n^2) (or worse) time.&lt;br /&gt;&lt;br /&gt;The first vertex welder I wrote was, well, slow. Welding a ~22,000 vertex mesh took over 12 seconds, and welding a smaller ~2300 vertex mesh took about 300ms. This was a completely unacceptable running time, as meshes are expected to run in the range of tens of thousands of vertices and a multi-minute loading time would be pure insanity.&lt;br /&gt;&lt;br /&gt;That vertex welder was a very simple implementation: for each vertex, search every other vertex and weld if needed. If a weld occurred, then scan through the index buffer and make the necessary corrections. At worst, this algorithm ran in O(n^3) time, because it would need to loop through the index buffer each time a vertex was welded (and the index buffer's size for a freshly loaded COLLADA mesh is directly proportional to vertex count). At best, it was O(n^2).&lt;br /&gt;&lt;br /&gt;I dumped that code and rewrote it from scratch, trading more memory usage for a better running time. I kept buffers which mapped vertices to welded vertices, and used this in a final, single loop over the index buffer to correct the indices. This brought the running time down to O((n^2+n)/2) (rather than between O(n^2) and O(n^3) like the old code). This dramatically improved running time: that 22,000 vertex mesh that took 12 seconds to load on the old code? 1.9 seconds on the new code.&lt;br /&gt;&lt;br /&gt;Running the code through a profiler revealed a few performance hotspots. At the top of the list was an incredibly expensive square root that was being used in the distance calculations. Factoring out the square root and making some misc. performance changes increased the performance by a factor of 4.&lt;br /&gt;&lt;br /&gt;But the algorithm was still too slow, O((n^2+n)/2) wasn't good enough. I needed to see if it would be possible to get it any faster. Rather than pine over micro optimisations in the code I had, I instead looked for a high-level algorithmic change.&lt;br /&gt;&lt;br /&gt;The most common optimisation for dumb collision detection is spatial partitioning. Spatial partitioning involves splitting up the entities into groups based on their position. There are many constructs to achieve this, such as BSP trees and kd-trees.&lt;br /&gt;&lt;br /&gt;I chose to use an octree. Octrees are a special case of kd-trees. Specifically, octrees are 3-dimensional kd-trees (and quadtrees are 2-dimensional kd-trees). Octrees are simple: divide up the search space into 8, equally sized, "octants". Each octant represents an eighth of the volume of the search space. Then for each octant, recursively split it into smaller and smaller octants until a desired limit is reached.&lt;br /&gt;&lt;br /&gt;This diagram, courtesy of wikipedia, demonstrates nicely:&lt;br /&gt;&lt;center&gt;&lt;a href=http://upload.wikimedia.org/wikipedia/commons/3/35/Octree2.png&gt;&lt;img src=http://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Octree2.png/400px-Octree2.png /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;After the octree is constructed and all the vertices are divided into neat little groups based on spatial position, the welding can begin. Welding the mesh then simply consists of going through each octant in the octree, and welding the octant's vertices. Since the number of vertices in each octant is much smaller than the original, the welding is done much faster.&lt;br /&gt;&lt;br /&gt;Usage of an octree reduces the time complexity from O(n^2) to average O(m(n / m)^2), where n is the total number of vertices and m is the total number of partitions in the octree. This can be simplified down to simply O(n^2/m). But what to choose for m? In other words, how many partitions should we create in the octree?&lt;br /&gt;&lt;br /&gt;I chose a value of (sqrt(n) / 4). Why? No idea. It's a magic number, and it worked reasonably well. sqrt(n) would mean that the average number of vertices in each partition would be equal to the number of partitions. But the more partitions you create, the more overhead the octree has. But if you have too few partitions, the welding's going to take too long for each partition. It's a fine balance, and sqrt(n) / 4 seemed to work well.&lt;br /&gt;&lt;br /&gt;This means that, when using the octree, the vertex welding algorithm is not quite O(n) linear time, but it's certainly a lot better than O(n^2). Here are the benchmark times:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;~2,000 Vertex Ducky:&lt;br /&gt;Original: 306ms&lt;br /&gt;Profiled + Reoptimised + Octree: [Too fast to measure]&lt;br /&gt;&lt;br /&gt;~12,000 Vertex Torus&lt;br /&gt;Profiled + Reoptimised: 4181ms&lt;br /&gt;Profiled + Reoptimised + Octree: 46ms&lt;br /&gt;&lt;br /&gt;~22,000 Vertex Lunar Rover:&lt;br /&gt;Original: 12768ms&lt;br /&gt;Optimised: 1966ms&lt;br /&gt;Profiled + Reoptimised: 468ms&lt;br /&gt;Profiled + Reoptimised + Octree: 47ms&lt;br /&gt;&lt;br /&gt;100,000 Vertex Sphere:&lt;br /&gt;Profiled + Reoptimised: 489484ms&lt;br /&gt;Profiled + Reoptimised + Octree: 686ms&lt;/blockquote&gt;&lt;br /&gt;As you can see, using the octree has resulted in a very significant improvement in speed. Completely welding a 100,000 vertex sphere now takes only 686ms compared to 489484ms, which is in excess of a 700x improvement in speed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8385844292068407786?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8385844292068407786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8385844292068407786' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8385844292068407786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8385844292068407786'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/optimising-vertex-welder-adventures.html' title='Optimising the Vertex Welder: Adventures Into Spatial Partitioning'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7470355062843259426</id><published>2008-04-02T18:16:00.004+11:00</published><updated>2008-04-02T20:41:26.101+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging Horrors'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Debugging Horrors: The case of the rogue #pragma pack</title><content type='html'>&lt;a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=488586"&gt;Here's&lt;/a&gt; a tale of horrors of #pragma pack. I already posted quite a bit about the issue over on that thread at GameDev.Net, so I won't bother reposting it here. It's an interesting read into solving a particular, very strange, bug.&lt;br /&gt;&lt;br /&gt;The gist of the issue was that I forgot to disable a particular #pragma pack in one of my headers - causing the packing rules to propogate down into the FCollada header files. Because of this, the compiler got the padding and offsets wrong, which resulted in corrupted this pointers all over the place.&lt;br /&gt;&lt;br /&gt;It was, by far, my most harrowing debugging experience. However, it was an experience not to be forgotten. And it was an excellent showcase for Visual Studio's amazing debugging capabilities. I'm not kidding here; Visual Studio has the best and easiest to use debugger ever. &lt;strong&gt;Period&lt;/strong&gt;. I really doubt I could have resolved this bug without the awesome debugger in VS.&lt;br /&gt;&lt;br /&gt;But, my crashing problems were still not resolved. Even after I fixed that rogue #pragma pack, the code ran fine in Debug mode. But crashed in Release mode. Since I couldn't really use the debugger in release mode, I had no idea what was going on. The capabilities of the debugger are castrated in release mode, since release mode is supposed to be for final production-level code, and has no debugging facilities.&lt;br /&gt;&lt;br /&gt;All I knew was that the crash was occurring even before WinMain() was hit. Which meant that something funky was going on. The debugger did still help, even though was in release mode. The code that was causing the crash was a static variable in one of FCollada's classes: a tree class of some sort.&lt;br /&gt;&lt;br /&gt;A quick look at the code in the tree class revealed this little fact: the constructor of the tree class allocated some memory through a global memory handler. The global memory handler was just a global variable, a function pointer, that was initialised to malloc/free. Whenever an allocation was made, this function pointer would be used to allocate memory.&lt;br /&gt;&lt;br /&gt;Experienced programmers should see the bug. It's a very subtle way to crash your program, and is difficult to track down. It's known as the &lt;a href="http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12"&gt;Static Initialisation Order Fiasco&lt;/a&gt;. Global variables do not have a defined order of initialisation in C++ - it all depends on how the compiler was feeling that day. In other words, initialisation order is effectively random.&lt;br /&gt;&lt;br /&gt;So what was actually happening? Well, the global tree variable was being initialised before the memory manager was. That meant that in the constructor for the tree, it was trying to allocate some memory. But since the memory manager hadn't even been initialised yet, the entire program crashed before it had even hit main()!&lt;br /&gt;&lt;br /&gt;Up to this point, everyone had just gotten lucky. The compiler had, for some reason, decided to always intitialise the memory manager first. So the memory manager was initialised and ready to go by the time the tree was constructed. But when I recompiled the code, my compiler decided to do it in the reverse order which crashed the program with a difficult-to-detect bug.&lt;br /&gt;&lt;br /&gt;This is one of the things that makes globals so damn dangerous - the static initialisation order fiasco gives your program a 50/50 percent chance of dying. And it's random. As the &lt;a href="http://www.parashift.com/c++-faq-lite/index.html"&gt;C++ FAQ Lite&lt;/a&gt; deftly noted, it's like playing russian roulette with half the chambers loaded.&lt;br /&gt;&lt;br /&gt;Needless to say, I &lt;a href="https://sourceforge.net/forum/forum.php?thread_id=1990422&amp;forum_id=460918"&gt;left a post informing the developers about it&lt;/a&gt; and posted a fix. FCollada is no longer managed by Feeling Software; they relegated the responsibility to the open source community. It remains to be seen whether they'll actually fix this bug, but I'm not hopeful. In the meantime, I've fixed the bug on my local copy of the source code, and now my COLLADA loader is working fine.&lt;br /&gt;&lt;br /&gt;Stay tuned for next time: Optimising the mesh loader.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7470355062843259426?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7470355062843259426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7470355062843259426' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7470355062843259426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7470355062843259426'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/04/debugging-horrors-case-of-rogue-pragma.html' title='Debugging Horrors: The case of the rogue #pragma pack'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8677696098466454288</id><published>2008-03-28T13:11:00.004+11:00</published><updated>2008-03-28T15:20:23.821+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='SCALE'/><title type='text'>SCALE III, part 4</title><content type='html'>The SCALE API is as simple as it gets. It consists of just two functions: ParseFromFiles() and ParseFromMemory(). The ParseFromFiles() function takes an array of filenames, loads the files into memory, and passes them to ParseFromMemory().&lt;br /&gt;&lt;br /&gt;ParseFromMemory() itself takes an array of strings, each string in the array represents a translation unit. Inside ParseFromMemory(), the SCALE engine is initialised and parsing occurs.&lt;br /&gt;&lt;br /&gt;The SCALE Engine has 2 distinct stages: tokenisation and parsing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tokenisation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Tokenisation of a translation unit is the process of breaking up the entire translation unit into separate entities known as "lexemes". A lexeme is the smallest "unit" that SCALE understands - they are analogous to words in english.&lt;br /&gt;&lt;br /&gt;In English, lexemes (eg, "run", "play", "discombobulate") are delimited by whitespace. That means, lexemes (or words) are defined to be separated by whitespace - if there's a bunch of characters that aren't separated by whitespace, it's considered to be a single word.&lt;br /&gt;&lt;br /&gt;I'm sure that I'm about to be mob lynched by all the linguists out there, so I think I'll stop with the analogies to real languages. In SCALE, lexemes are delimited by a certain number of characters which where described in &lt;a href="http://adtsai.blogspot.com/2008/03/scale-iii-part-2.html"&gt;part 2&lt;/a&gt; of this series. It's the tokeniser's job to break apart the entire translation unit into lexemes that then go into the parsing stage. For example, let's say we have the following translation unit:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Type ObjectName&lt;br /&gt;{&lt;br /&gt;    ~Frobnicate&lt;br /&gt;    {&lt;br /&gt;        Foo = 5;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The tokeniser would break up that code into the following list of tokens:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Lexeme          Index     Row, Column&lt;br /&gt;"Type"          0         1,   1&lt;br /&gt;"ObjectName"    5         1,   6&lt;br /&gt;"{"             17        2,   1&lt;br /&gt;"~Frobnicate"   24        3,   5&lt;br /&gt;"{"             41        4,   5&lt;br /&gt;"Foo"           52        5,   9&lt;br /&gt;"="             56        5,   13&lt;br /&gt;"5"             58        5,   15&lt;br /&gt;";"             59        5,   16&lt;br /&gt;"}"             66        6,   5&lt;br /&gt;"}"             69        7,   1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, whitespace and comments are ignored - only the useful information is extracted. This list of tokens is then passed to the parser.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Parsing&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The job of the parser is to make sense of the raw tokens given to it by the tokeniser. At its core, the SCALE parser's job is to check syntax and format/convert the information into useful data structures. The parser is responsible for type checking, syntax &amp;amp; formatting, and conversion of data. The parser just sequentially runs through each token in the list, and performs checking to ensure that it's correct. If an unexpected token is found (eg. missing an opening brace), the parser errors out. When parsing object types, object names, modules, variable names and variable values, the parser does checks to ensure the validity of the token and enforces things like naming rules and types.&lt;br /&gt;&lt;br /&gt;The output of the parser is a large associative data structure (a std::map&lt;&gt;, specifically) called ParsedData. The ParsedData structure contains all the types which were parsed by the parser. ParsedData is a std::map whose key is a type name, and whose key values is a data structure called TypeData.&lt;br /&gt;&lt;br /&gt;The TypeData structure contains all the parsed objects that are of the specified type. It, too, is a std::map associative container. The key value is an object name, and the key value type is a structure called ObjectData.&lt;br /&gt;&lt;br /&gt;The ObjectData structure contains all the modules contained in a particular object. Like the other data structures, this is another associative container (std::map). The key is a module name, and the key value is an array of "ModuleData" data structures (remember, it's legal to have multiple modules of the same name in an object).&lt;br /&gt;&lt;br /&gt;The ModuleData structure finally contains a map of all the variables in that module. The map's key is a variable name, the value is a VariableData structure.&lt;br /&gt;&lt;br /&gt;Finally, the VariableData structure contains the data for a variable, including the type.&lt;br /&gt;&lt;br /&gt;If you didn't understand that, here's a helpful diagram that may help:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://img245.imageshack.us/img245/2528/scaleik0.png" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SCALE III, as the name implies, is the third time I've attempted to implement SCALE. The first iteration was, well, terrible. It was slow and incredibly fragile with overly strict and verbose syntax. It was abandoned quite quickly, and SCALE II was born. SCALE II had the exact same syntax and naming/typing rules as SCALE III, but it's impementation was very different. SCALE II was an attempt at single-pass lexical analysis. There was no tokenisation or parsing or compiling phase, it was all done in-place. And it was a bloated, slow, complex piece of code. I had believed that I could save some performance by making it single pass - but it was a lot more difficult than I would have imagined. That's why SCALE III is done in two passes, like a lot of other lexers out there.&lt;br /&gt;&lt;br /&gt;SCALE II relied heavily on simple arrays to store data - and searching arrays was pretty slow as it was an O(n) operation. For namespace collisions and type checking, this resulted in a terrible O(n^2) running time. SCALE III now relies on sorted associative arrays: std::map is usually implemented as a binary red-black tree and it guarantees O(log n) time complexity when searching, indexing, inserting and removing from the tree. Thanks to this, large portions of the engine were optimised from O(n^2) running time to O(n log n), which is a very significant improvement.&lt;br /&gt;&lt;br /&gt;SCALE III also supports multithreaded processing of translation units (well, SCALE II did as well, but it wasn't quite as robust). Since translation units can be processed separately, they are dispatched to a thread pool where they are processed in parallel. Since name resolution and checking across translation unit boundaries requires that all the information be available, it's delayed until all translation units have been processed. Then, the thread pool is destructed and namespace resolution occurs on a single thread. That means that some of the processing is required to be serial, but the majority of processing (tokenisation, most of the parser) can be run in parallel for a significant performance increase over single-threaded processing.&lt;br /&gt;&lt;br /&gt;Here are some benchmark results on my processor (Core 2 Duo E6600):&lt;br /&gt;&lt;blockquote&gt;2x 7.5mb files (15mb total), MT OFF: &lt;strong&gt;6505ms&lt;/strong&gt;&lt;br /&gt;2x 7.5mb files (15mb total), MT ON: &lt;strong&gt;3679ms&lt;/strong&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;With multithreading on, the total running time is reduced by 43%. That means that with multithreading on, SCALE is over 76% faster! Of course, I only have a dual core to test it on. The gains would be even larger on a quad core, or octo core. This multithreaded system is scalable up to the number of translation units available, so benefits would likely be seen up to 16-core and beyond, given that there's likely to be a large number of translation units.&lt;br /&gt;&lt;br /&gt;Of course, it certainly could be faster. I haven't even run SCALE through a profiler yet, since there's practically no need to optimise. In any sane, non-pathological real-world case, we'd be looking at miniscule amounts of data. At most, maybe 1mb of text data spread out across dozens of files. Since the loading is faster on lots of small files as opposed to a couple of large files, SCALE can parse an entire game's worth of data almost instantly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8677696098466454288?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8677696098466454288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8677696098466454288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8677696098466454288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8677696098466454288'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/scale-iii-part-4.html' title='SCALE III, part 4'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-6263584013467866366</id><published>2008-03-24T14:28:00.015+11:00</published><updated>2008-04-02T19:45:04.943+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='SCALE'/><title type='text'>SCALE III, part 3</title><content type='html'>&lt;strong&gt;The Type System&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Variables in SCALE do not have types, unlike objects (eg. an object "SpriteMaterial" having a type of "Material"). Or not explicit types, anyway. The user does not specify the type of a variable. Nor does the application, for that matter. A variable can have any type, and this type is determined at runtime by the SCALE parser. There are 12 fundamental types that SCALE recognises:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;- &lt;span style="color:#3333ff;"&gt;Integer&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;Boolean&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;Float&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;Reference&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;Enumeration&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;String&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;IntegerArray&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;BooleanArray&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;FloatArray&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;ReferenceArray&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;EnumerationArray&lt;/span&gt;&lt;br /&gt;- &lt;span style="color:#3333ff;"&gt;StringArray&lt;/span&gt; &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;When a variable's value is parsed, the type is dynamically determined based on a set of rules. Right now, the rules are a bit arbitrary and will need to be formalised and set in stone sometime in the future. But for now, this the general algorithm:&lt;br /&gt;&lt;pre class="code"&gt;  - If the value is surrounded by braces ('{' and '}'), it is an array. For each element, use this algorithm to determine the type.&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;  - Else, if the value is surrounded by quotes ('"'), it is of type String&lt;br /&gt;  - Else, If the value is preceeded by an ampersand ('&amp;amp;'), it is of type Reference&lt;br /&gt;  - Else, If the value is "true" or "false" (sans quotes), it is of type Boolean.&lt;br /&gt;  - Else, if the value is a numeric value&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;      - If the value has a decimal point ('.'), it is a Float&lt;br /&gt;      - Else, the value is an Integer&lt;br /&gt;  - Else, it is of type Enumeration.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; Arrays must be homogeneous; that is, the types of all elements must be identical. Arrays of arrays are not supported.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Determination of whether a value is "numeric" is currently a bit arbitrary. Needs to be finalised in the future.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once SCALE determines the type, it converts it into a binary format and gives it to the application. It is the application's job to determine what to do with it, and what to do if the type isn't what was expected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Naming&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In SCALE, each object must have a unique name. That is, it is illegal for two objects to share a name.&lt;br /&gt;&lt;br /&gt;Each type has its own namespace. Which means that the unique name requirement doesn't carry between two different types. For example: it's legal to have an object of type "Foo" to be called "Fred", and at the same time to have an object of type "Bar" to also be called "Fred". This is legal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Bar Fred&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Foo Fred&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's a gotcha, though. You'd expect that each translation unit would get its own namespace, but it doesn't work that way. All translation units share the same, global namespace. Meaning that separating two identically typed, identically named objects into two different translation units (or files) won't work.&lt;br /&gt;&lt;br /&gt;This unique name rule doesn't apply to modules in an object - it is legal to have two modules of the same name (and even containing the same data, if you wanted). This is legal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Type ObjectName&lt;br /&gt;{&lt;br /&gt;    ~Frobnicate&lt;br /&gt;    {&lt;br /&gt;        Foo = 5;&lt;br /&gt;    }&lt;br /&gt;    ~Frobnicate&lt;br /&gt;    {&lt;br /&gt;        Foo = 6;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The rule rears its ugly head again when dealing with variables. Every module, in every object, gets its own namespace. What that means is that in any particular module, you're not allowed to have two variables with the same name. However, you are obviously allowed to have two variables with the same value. For example, the following is &lt;strong&gt;NOT&lt;/strong&gt; legal, and will cause an error during parse time:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Type Wilma&lt;br /&gt;{&lt;br /&gt;    ~Fred&lt;br /&gt;    {&lt;br /&gt;        Foo = 5;&lt;br /&gt;        Foo = 6;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's about it as far as naming and type rules go - it's relatively simple and easy to remember.&lt;br /&gt;&lt;br /&gt;Next time, I'll talk about the usage of the SCALE API from the perspective of the application, and how it's going to be used with SolSector.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-6263584013467866366?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/6263584013467866366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=6263584013467866366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6263584013467866366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6263584013467866366'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/scale-iii-part-3.html' title='SCALE III, part 3'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-7196202333006287728</id><published>2008-03-23T23:04:00.004+11:00</published><updated>2008-03-24T15:22:15.774+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='SCALE'/><title type='text'>SCALE III, part 2</title><content type='html'>&lt;strong&gt;So what the heck does it even do? What does it look like?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SCALE defines a syntax format and provides a parser for that syntax. That's basically all that SCALE is. As I mentioned in my previous post, SCALE was inspired by and is based upon the .ini configuration files of Command and Conquer: Generals. A key feature of C&amp;amp;C:G's .ini system was its devilish simplicity. The syntax was simple and easy to understand - they were, after all, just configuration files (hence the .ini extension).&lt;br /&gt;&lt;br /&gt;So here's what the syntax of SCALE looks like:&lt;br /&gt;&lt;pre&gt;Material SpriteMaterial&lt;br /&gt;{&lt;br /&gt;    ~Shader&lt;br /&gt;    {&lt;br /&gt;        Filename = "Sprite.fx";&lt;br /&gt;        TechniqueName = "Sprite2D";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ~ShaderPass&lt;br /&gt;    {&lt;br /&gt;        PassName = "Pass0";&lt;br /&gt;        RenderTarget = &amp;BackBuffer;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ~ShaderConstants&lt;br /&gt;    {&lt;br /&gt;        WorldMatrix = "WorldMatrix";&lt;br /&gt;        OrthoProjectionMatrix = "OrthoProjectionMatrix";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ~Texture&lt;br /&gt;    {&lt;br /&gt;        Filename = "laying_rock7_largeDXT5.dds";&lt;br /&gt;        ShaderBinding = "Texture";&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, the syntax is really simple. It's broken up into a simple hierarchy:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-Translation Units&lt;br /&gt;    -Objects&lt;br /&gt;        -Modules&lt;br /&gt;            -Variables&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;At the top, you have translation units. They're analogous to C/C++ translation or compilation units, in that they are effectively separate "modules". Each translation unit can be parsed without needing to look at any other translation units.&lt;br /&gt;&lt;br /&gt;Each translation unit is typically represented by a file, but no limitation is imposed by the parser. Inside each translation unit is any arbitrary number of objects. Each object can be of any arbitrary type. Each object can also hold an arbitrary number of modules. And each module can hold an arbitrary number of arbitrarily typed variables with arbitrary values.&lt;br /&gt;&lt;br /&gt;Confused? Let's take another look at the syntax we saw above. That code is actually an entire object - named "SpriteMaterial". The type of this object is a "Material". This works the same way as declaring variables C/C++: declare a type, then the variable name. In the body of the object, you are allowed any number of modules. A module is signified by the tilde prefix ('~'). For example, there are 4 modules in the above object: "Shader", "ShaderPass", "ShaderConstants", and "Texture". SCALE allows any number of modules, and they can have any name. SCALE also allows duplicate named modules - for example, it is legal to declare two modules named "Texture". Inside each module is a set of variables. SCALE also allows any number of variables, and they can be named however the application wishes.&lt;br /&gt;&lt;br /&gt;Two types of comments are supported in SCALE: C-style comments and C++ style comments. Comments are merely skipped by the parser. They act just like they do in C++:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Foo Wilma&lt;br /&gt;{&lt;br /&gt;    ~Bar&lt;br /&gt;    {&lt;br /&gt;        Baz = 12.0;&lt;br /&gt;        //Baz = 3.14;&lt;br /&gt;    }&lt;br /&gt;    /*~Fred&lt;br /&gt;    {&lt;br /&gt;    }*/&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Like in many languages, whitespace is mostly irrelevant in SCALE and has no syntactic meaning. Tokens in SCALE are delimited by a few things: &lt;br /&gt;- Comments&lt;br /&gt;- Braces&lt;br /&gt;- Newlines&lt;br /&gt;- Whitespace&lt;br /&gt;- Semicolon&lt;br /&gt;- Equals sign&lt;br /&gt;&lt;br /&gt;That means that you can separate two identifiers with any of the above constructs. For example: this is entirely legal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Mesh/*comment*/MyMesh{&lt;br /&gt;  ~File&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;        Name="fromage";&lt;br /&gt;      LazyLoad      =   /* hi, ma */ false;}&lt;br /&gt; ~Options{WeldVertices=true;Epsilon=0.01;}~Foo{Something=42;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It's just unreadable, that's all.&lt;br /&gt;&lt;br /&gt;So that's the syntax of SCALE. Very easy to understand and remember. In my next post, I'll go into the variable typing system, and describe the naming system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-7196202333006287728?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/7196202333006287728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=7196202333006287728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7196202333006287728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/7196202333006287728'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/scale-iii-part-2.html' title='SCALE III, part 2'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4712250205808973412</id><published>2008-03-23T12:41:00.007+11:00</published><updated>2008-11-14T07:15:05.478+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='SCALE'/><title type='text'>SCALE III</title><content type='html'>&lt;strong&gt;"SCALE"?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;SCALE is a wonderful little backronym that a friend and I came up with back in 2006. It stands for "Scalable Contant Abstraction Layer Engine". It's an overly fancy name for a helper library designed for usage in data-driven games.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;History&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Before I began dabbling in hobbyist game development, I liked to make mods for games. Back in 2003, I joined the &lt;a href="http://halogen.slipstreamproductions.net/"&gt;Halogen &lt;/a&gt;team, which aspired to create a Halo total conversion mod for Command and Conquer: Generals. Following the disappearance of their existing coder at the time, I quickly assumed the role of lead coder for the project - and remained sole coder until the project ended in late 2006.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5180753190803584258" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_Ae8yfa48_SM/R-W7lAbRtQI/AAAAAAAAAB0/Hi3oKfXCCqI/s400/halogensc42.jpg" border="0" /&gt;&lt;br /&gt;Halogen was actually reasonably close to completion. By the middle of 2006, most of the UNSC faction was complete, and the Covenant units and structures were well on their way. We had plans for an open beta in mid-late 2006. By that time, Halogen had gained a reasonably large amount of popularity. We were well known in the C&amp;amp;C modding community, and we also made a small name for ourselves in the Halo community. Our updates were often mentioned on the front page of &lt;a href="http://halo.bungie.org/"&gt;halo.bungie.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In September 2006, we effectively recieved a cease and desist letter. It wasn't actually sent by Microsoft, though. SketchFactor, a community manager at Bungie, elected to inform us of the bad news before Microsoft's lawyers got involved. And so, after 3 years of working on Halogen, &lt;a href=http://www.joystiq.com/2006/09/13/ms-shuts-down-halogen-mod-why-now/&gt;we&lt;/a&gt; &lt;a href=http://www.1up.com/do/newsStory?cId=3153524&gt;officially&lt;/a&gt; &lt;a href=http://forums.bungie.org/halo/archive25.pl?read=741190&gt;shut&lt;/a&gt; &lt;a href=http://www.gamesfirst.com/?id=1418&gt;down&lt;/a&gt; &lt;a href=http://www.gamesetwatch.com/2006/09/gamesetinterview_slipstream_pr.php&gt;the&lt;/a&gt; Halogen project. If you google "halogen mod" you may still be able to find some online articles if you want more information.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img id="BLOGGER_PHOTO_ID_5180752464954111202" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_Ae8yfa48_SM/R-W66wbRtOI/AAAAAAAAABk/Kzng9v5cjb0/s400/sshot127.png" border="0" /&gt;&lt;br /&gt;&lt;img id="BLOGGER_PHOTO_ID_5180752830026331378" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_Ae8yfa48_SM/R-W7QAbRtPI/AAAAAAAAABs/8IA_au5hIoQ/s400/sshot142.png" border="0" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Of course, it was no secret why were were shut down. A few weeks after the notice, at &lt;a href="http://en.wikipedia.org/wiki/X06"&gt;X06&lt;/a&gt;, Microsoft's new Halo RTS "Halo Wars" was announced. Since Command and Conquer: Generals was an EA game, Halo was Microsoft's intellectual property, and Halogen was going to be direct competition, it's obvious why we were shut down.&lt;/p&gt;&lt;p&gt;But I never forgot the experience I gained through Halogen. Command and Conquer: Generals was an extremely moddable game - practically all game assets were exposed through a simple, easy to use plain text system. All in-game entity definitions were changeable through regular .ini files - making modding a breeze. This extreme moddability is what kept Command and Conquer: Generals alive for so long. Through my experience on Halogen, I learned the value of highly data-driven game design.&lt;/p&gt;&lt;p&gt;That's what SCALE is. It's not just a format, it's an engine for data-driven assets, based loosely on the .ini modding system used in Command and Conquer: Generals. Effectively, C&amp;amp;C:Generals was my inspiration for designing this system, and the great time I had modding it provides the motivation for SCALE's implementation.&lt;/p&gt;&lt;p&gt;Now that my overly lengthy history lesson is over, I'll begin talking about SCALE itself in more detail in a later post sometime.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4712250205808973412?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4712250205808973412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4712250205808973412' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4712250205808973412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4712250205808973412'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/scale-iii.html' title='SCALE III'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Ae8yfa48_SM/R-W7lAbRtQI/AAAAAAAAAB0/Hi3oKfXCCqI/s72-c/halogensc42.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-6669352706233722049</id><published>2008-03-22T08:52:00.004+11:00</published><updated>2008-04-02T20:42:17.833+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Macros</title><content type='html'>Once again I am boggled by the sheer evilness of macros. They're so innocent, like a cute little bunny. But the moment you turn your back you immediately find it gnawing on the back of your skull in an attempt to forcefully extract all of the remaining slivers of sanity which you hold so dear.&lt;br /&gt;&lt;br /&gt;After implementing exceptions in SolSector Engine, I turned to improving some other error-related code: asserts. asserts are handy little macros which basically make an assertion that a certain condition &lt;strong&gt;must&lt;/strong&gt; be true. Otherwise the program breaks. And it breaks loudly.&lt;br /&gt;&lt;br /&gt;In C/C++, you use it like this:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;assert(x != 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means that the variable x should never be equal to 0, and if it is the program will break and an "Assertion Failed" dialog box will pop up (on MSVC, that is). Asserts were intended to be debugging tools, so they are only active in debugging mode. That is, they're only active if NDEBUG is not defined. Otherwise, they're removed by the preprocessor.&lt;br /&gt;&lt;br /&gt;I see a little problem with this. All too often, I find that a particular problem happens when compiling in release mode, but for some reason doesn't happen in debug mode. In debug mode, code is compiled with no optimisations, and with full debugging information on. And it's often that it feels like I've got some freaky quantum errors going on... the errors magically disappear when I try to observe and debug them.&lt;br /&gt;&lt;br /&gt;In debug mode, things like RTTI, exceptions, strict floating point precision, and optimisations are all turned off. That's a lot of different variables between release and debug mode to test - it means that if an error occurs in release but not debug mode, then any of the differences between the two modes are causing the problem. For example, the lack of RTTI may be making a dynamic_cast fail somewhere in release mode but not in debug mode. The lack of floating point exceptions might be screwing with math calculations somewhere. And the list goes on.&lt;br /&gt;&lt;br /&gt;Turning asserts (aka. a vital debugging tool) off in release mode only exacerbates the problem. An assert might catch something that would be causing the error in release mode - but because the default library assert is tied to debug mode, I needed to write my own so that I could toggle it on/off at will without having to rely on NDEBUG. Having a custom assert also means that I don't have to deal with that ugly default MSVC-generated "assertion failed" dialog box.&lt;br /&gt;&lt;br /&gt;Searching for resources, &lt;a href="http://powerof2games.com/node/10"&gt;I came across this article&lt;/a&gt;. Read it. &lt;strong&gt;Now&lt;/strong&gt;. If you didn't think macros were evil before, you should after reading that. It's not to say that macros shouldn't be used (indeed, assert is a perfectly valid use for a macro), but it highlights just how difficult macros can be. The average programmer should be wary of writing macros because, more often than not, you'll get them wrong.&lt;br /&gt;&lt;br /&gt;I'm not even going to attempt writing my own assert macro now, and instead will use the one in the aforementioned article (it was released under the MIT license). And I can see that some of my existing macros need to be fixed. The mind-boggling evilness of macros strikes again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-6669352706233722049?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/6669352706233722049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=6669352706233722049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6669352706233722049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/6669352706233722049'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/macros.html' title='Macros'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-3443691678813598779</id><published>2008-03-20T16:48:00.005+11:00</published><updated>2008-04-02T20:42:47.887+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Exceptions vs. Error Codes</title><content type='html'>&lt;p&gt;When I first started SolSector engine, I was faced with a bit of a dilemma. I had to choose how to perform error reporting and recovery. I had two choices: error codes or C++ exceptions.&lt;br /&gt;&lt;br /&gt;Error codes, like the HRESULT returns that DirectX uses, have bern tried and tested. They work well, and they're fast. However, they're a pain to manage. For every function that can possibly return an error, you need to check the return code. With hundreds of functions, this can be a major pain. Often, an error occurs deep in a function stack, and that error would need to be propagated through all the functions until it gets to higher function that can actually do something about the error. However, error codes are fast and really simple to use.&lt;br /&gt;&lt;br /&gt;Exceptions, on the other hand, seem to be hated by a lot of people. I'd heard of the horrid execution speed of exceptions, and the apparent difficulty of writing exception-safe code. For instance:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span style="color:#3333ff;"&gt;void&lt;/span&gt; foo(&lt;span style="color:#3333ff;"&gt;char&lt;/span&gt;*, &lt;span style="color:#3333ff;"&gt;char&lt;/span&gt;*);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#3333ff;"&gt;void&lt;/span&gt; bar()&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;foo(&lt;span style="color:#3333ff;"&gt;new char&lt;/span&gt;[5], &lt;span style="color:#3333ff;"&gt;new char&lt;/span&gt;[5]);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;What's wrong with this code? Well, either one of those new's can throw an exception. Depending on how the compiler is feeling today, this could cause a memory leak because if an exception is thrown, foo() will never execute and the pointer to the allocated memory will be lost forever. I'm sure you can think of many more similarly nasty cases.&lt;/p&gt;&lt;p&gt;Initially, I chose to use error codes because of all the negative criticism regarding exceptions. And error codes worked well. I wrote a bunch of helpful macros to facilitate automatic error code returns and logging. But, as the project grew, error codes became more and more of a problem. Because error codes are only integers, they cannot store additional semantic information. For example, if a mesh loading function failed to load a file, I'd like to be able to know what the filename was. To alleviate this, I wrote a logging system so that whenever an error was returned from a function, it would automatically log the error (along with any additional helpful error/debugging information) in a global logger class. The returned error code would then be an index to the logged error message.&lt;br /&gt;&lt;br /&gt;As you can imagine, this was very ugly. It seemed hackish and didn't feel like a clean solution (trying to hide all this ugly logging business behind macros, etc). It was at this point that I began to seriously consider exceptions.&lt;br /&gt;&lt;br /&gt;I asked myself, why did I choose to avoid exceptions in the first place? I had a few main reasons:&lt;br /&gt;Performance. I feared that exceptions would prove to be unacceptably slow.&lt;br /&gt;Maintainability. I had heard that exceptions were notoriously difficult to work with and that it was hard to write exception-safe code.&lt;br /&gt;Experience. Back when I began SolSector Engine (2006-ish) I hadn't had a large amount of experience working with exceptions yet. But I was already quite comfortable with error codes. Not having much experience with exceptions exacerbated my fears that I would not be able to write proper exception safe code.&lt;br /&gt;&lt;br /&gt;I reviewed these reasons, and did a lot of research on the topic. As it turns out, my performance fears were unfounded. There were two things I was initially concerned about: the intrinsic cost of having exceptions on, and the cost of actually throwing an exception.&lt;br /&gt;&lt;br /&gt;The intrinsic cost of exceptions is no lower than regular error codes. The general gist of it is that in any decent compiler, compiling with exceptions on just means that a function pointer (representing the exception handler) is popped on/off the stack when a function is entered/exited. Of course, there's probably more involved in the process, but calling a function with exceptions on is no more expensive than calling it and returning an error code. Another critical point is this: the standard library uses exceptions. If I want to catch out-of-memory errors and the like, I'd need exceptions to be on, anyway.&lt;br /&gt;&lt;br /&gt;Of course, actually throwing an exception is quite slow. But let's stop and think for a moment. When are exceptions thrown? Exceptions are only thrown when an error happens. And when an error occurs, performance is the least of my worries. A great saying is, "throw exceptions in exceptional circumstances". If you're using exceptions for regular flow control, then you've got bigger problems than mere performance issues. This is also a great example of premature optimisation (which, as we all know, is the root of all evil). When an error occurs, it is far more important to have a useful error reporting system, rather than jumping through hoops and sacrificing code usability/maintainability (like I did with the logging system for error codes) to achieve better performance.&lt;br /&gt;&lt;br /&gt;Maintainability of exceptions isn't that bad. Sure, writing exception-safe code is hard (very hard). But, it's not as bad as I would have imagined. Ever since I started using C++, I realised the value of RAII. For those of you who don't know, RAII stands for "Resource Acquisition Is Initialisation" and is pretty self-explanatory. Its meaning extends to deallocation - when an object is destroyed, it should clean up its own mess. In C++, this is made possible by the use of destructors: when an object is delete'd or goes out of scope, its destructor is called. My extensive use of RAII means that exception-safe code is an order of magnitude easier - when I throw an exception, I know that all my objects that I allocated on the stack will be cleaned up. And since I almost never deal with raw pointers (learn to love smart pointers!), I don't even have to worry about the memory I allocated in a function. With the usage of good, idiomatic C++, the maintenance costs if exceptions are lowered.&lt;br /&gt;&lt;br /&gt;Recently, I've been using the .NET framework a lot more. In particular, I was exposed to C# while I was participating in the &lt;a href="http://code.google.com/opensource/ghop/2007-8/"&gt;Google Highly Open Participation Contest&lt;/a&gt;, where I worked on improving the performance of the Mono C# Compiler. The compiler itself was written in C#, and I was able to increase the performance of the compiler by 5-10%. That's where I picked up C# - I learned it on the spot as I read through real code, learning as I went along. Exposure to such a "modern" language showed me the value of exceptions - error handling in .NET was far, far easier and more elegant than in SolSector Engine, for example. I could just set up a try/catch block around something, and if anything went wrong I could deal with it appropriately. In .NET, no more did I have to deal with massive blocks of if statements and error code checks.&lt;/p&gt;&lt;p&gt;So I finally made the jump to exceptions for SolSector Engine. Thanks to some handy macros and the power of regex, it only took me a few days to do (although testing will take much, much longer). It's still very early, but they seem to be working well so far and I haven't encountered any major problems. The error system is now a lot more robust and easy to use, I think. I got rid of the logging contraptions I used for error codes, and stored information inside exceptions themselves - much more convenient. The new code integrates better into the STL, too. Rather than setting up massive try/catch blocks and attempting to convert standard exceptions into error codes, I can now just &lt;em&gt;not bother&lt;/em&gt; and allow the exceptions to pass through. It's the same with constructors - exceptions are the best way to signal a failed constructor.&lt;/p&gt;&lt;p&gt;I wrote my exceptions to be similar to those found in .NET - as they were simple and familiar. It's still early, and lots of testing needs to be done, but for now it seems that I made the right choice. From now on, it'll be exceptions all the way.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-3443691678813598779?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/3443691678813598779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=3443691678813598779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3443691678813598779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/3443691678813598779'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/when-i-first-started-solsector-engine-i.html' title='Exceptions vs. Error Codes'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-4592537444625241362</id><published>2008-03-17T21:51:00.011+11:00</published><updated>2010-11-24T12:13:00.513+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Clouds'/><category scheme='http://www.blogger.com/atom/ns#' term='HDR'/><title type='text'>Implementing HDR in Clouds</title><content type='html'>It seems as if High Dynamic Range lighting (HDR) is becoming all the rage for gaming graphics, nowadays. I’ve seen it used in a multitude of games thus far. I remember my first HDR experience. It was back in 2004, when FarCry had just released its 1.3 patch enabling HDR on Geforce 6 series cards. Since I was between upgrades, I was using a Radeon X300 at the time. So I went to a friend’s house to try it out on his 6600GT. And I was stunned at the oversaturated, glaring bloom effects.&lt;br /&gt;&lt;br /&gt;I’d wanted to implement my own over-the-top HDR ever since.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What is HDR?&lt;/strong&gt;&lt;br /&gt;So for the uninitiated, what is HDR? In the real world, we humans experience a vast range of contrast. We can see very bright objects, such as the sun, as well as very dark objects such as a moonlit scene. In computers and modern graphics, however, we're limited to a very, very small range. The brightest colour that can be expressed in a 32-bit ARGB texture is (255, 255, 255, 255), or pure white. And it isn't very bright. So we use a technique called HDR to alleviate this. When rendering the scene, we render it to a format with a very high dynamic range, for example a 64-bit texture. Most commonly, we use a floating point format in the form: A16R16G16B16F, which means a 16-bit float for each component. Each component can now roughly store a value up to about ~65,000... much better than the 255 we were limited to on 32-bit ARGB.&lt;br /&gt;&lt;br /&gt;That means that in our scene, very very bright objects will have colours greater than 255, while dark objects will be able to have precise values near 0 (thanks to floating-point). But now we've got a problem. Regular monitors and displays can't display such bright values: the hardware itself is still limited to 8-bit component RGB, with its annoying 255 maximum. So an operation called &lt;strong&gt;tonemapping&lt;/strong&gt; is performed. Tonemapping is the process of converting the HDR image into a Low Dynamic Range image (LDR), so that the monitor can actually display it. This means shifting and squeezing the brightness of a scene so that it best fits within the display limits of the monitor. This is why, in HDR-rendered scenes, the brightness changes as you look at bright/dark objects.&lt;br /&gt;&lt;br /&gt;After tonemapping, you've got an LDR image which you can now display to the monitor. That's really all that HDR needs. But if you've ever used a camera, you may notice some things are missing from our HDR scene. In a camera (and in the human eye), we see that bright things tend to get lens flares, as well as blooming. So often you'll see these things implemented along with HDR (and, indeed, seem to have become synonymous with the term). Bloom, starring and lens flares are all post-processing effects, and they simulate the effect of light passing through a lens and can greatly increase the image quality of a scene. More information can be found in the resources I'll list later on.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;HDR in Clouds&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Clouds doesn’t use any dynamic lighting. All shading done on the clouds is static – cheap shader approximations because I didn’t want to implement anything overly complicated. Nevertheless, I made the decision to implement HDR because it provided an excellent real-world test of SolSector Engine’s shader system.&lt;br /&gt;&lt;br /&gt;I set out by reading up on the relevant material. As HDR had gained popularity for use in games over the past few years, there was no shortage of information. The first thing I took a look at was the famous implementation by Masaki Kawase, in the form of his demo dubbed “Rthdribl” (Real-Time High Dynamic Range Image Based Lighting). It’s available &lt;a href="http://www.daionet.gr.jp/%7Emasa/rthdribl/"&gt;here&lt;/a&gt;. I used his demo as a base for what HDR should look like - and set out to write my own shaders in HLSL from scratch.&lt;br /&gt;&lt;br /&gt;The full HDR pipeline is pretty complex. I drew up an initial diagram for the pipeline: (warning: large)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://img247.imageshack.us/img247/7583/pipelinesmallzl3.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178671690756064082" style="display: block; margin: 0px auto 10px; text-align: center;" alt="" src="http://3.bp.blogspot.com/_Ae8yfa48_SM/R95WdwfjA1I/AAAAAAAAAA8/wTpaEwA5NaQ/s400/PipelineSmall.png" border="0" /&gt;&lt;/a&gt; But, this was unoptimised and took up a horrific amount of memory:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://img82.imageshack.us/img82/8029/resourcesummarysmallon4.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178671768065475426" style="display: block; margin: 0px auto 10px; text-align: center;" alt="" src="http://1.bp.blogspot.com/_Ae8yfa48_SM/R95WiQfjA2I/AAAAAAAAABE/Po-zUuOKc_o/s400/ResourceSummarySmall.png" border="0" /&gt;&lt;/a&gt; After some reorganisation, I was able to significantly reduce the amount of buffers to just a few, but it really convoluted the pipeline: (warning, very large)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://img528.imageshack.us/img528/1598/hdroptimised.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178672098777957234" style="display: block; margin: 0px auto 10px; text-align: center;" alt="" src="http://2.bp.blogspot.com/_Ae8yfa48_SM/R95W1gfjA3I/AAAAAAAAABM/fGGXczMeEn0/s400/PipelineSmall.png" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://img256.imageshack.us/img256/593/resourcesummarysmallhk1.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178676578428846994" style="display: block; margin: 0px auto 10px; text-align: center;" alt="" src="http://1.bp.blogspot.com/_Ae8yfa48_SM/R95a6QfjA5I/AAAAAAAAABc/14sED5tfHV4/s320/ResourceSummarySmall.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Problems&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One of the main problems was simply getting it to look right. Initially, I used the Reinhard operator to tonemap the HDR scene, but I found that it was ill-suited for this purpose. It would overdarken bright scenes, and overbrighten dark scenes. In other words, the dynamic range was a little &lt;em&gt;too&lt;/em&gt; high. After many, many hours of tweaking, I resorted to simply removing the Reinhard operator in favour of a simple linear one. The Reinhard operator (as well as the Reinhard improved operator) would simply reduce contrast over the entire scene to fit the HDR space into LDR - a byproduct of its hyperbolic curve, even if it did guarantee that the HDR scene mapped fully into LDR. It may have been theoretically ideal, but it just didn't look good. The linear operator, in addition to a simple luminance clamp, is certainly not "technically" correct. But it doesn't matter; it looks nice and the tonemapping effect is now quite subtle (as it should be).&lt;br /&gt;&lt;br /&gt;HDR is just one of those things that needs a lot of tweaking to get right. Especially the tonemapping, and various parameters for bloom/glare/etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For anyone looking to implement HDR for themselves, here are a few of the things that helped me along the way: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Masaki Kawase's GDC 2004 slides, available &lt;a href="http://www.daionet.gr.jp/%7Emasa/archives/GDC2004/GDC2004_PIoHDRR_EN.ppt"&gt;here &lt;/a&gt;and &lt;a href="http://www.daionet.gr.jp/%7Emasa/archives/GDC2004/GDC2004_PIoHDRR_SHORT_EN.ppt"&gt;here&lt;/a&gt;. Go through them both!&lt;/li&gt;&lt;li&gt;For those interested in some theory, be sure to check out Erik Reinhard's whitepaper &lt;a href="http://www.cs.utah.edu/%7Ereinhard/cdrom/tonemap.pdf"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The DirectX SDK samples. They provide full source code and explanations, and a heck of a lot of good information. See: &lt;a href="http://msdn2.microsoft.com/en-us/library/bb173486.aspx"&gt;HDR Lighting (Direct3D 9)&lt;/a&gt;, &lt;a href="http://msdn2.microsoft.com/en-us/library/bb173484%28VS.85%29.aspx"&gt;HDRLighting Sample &lt;/a&gt;(with executable and source code available the SDK), &lt;a href="http://msdn2.microsoft.com/en-us/library/bb173485%28VS.85%29.aspx"&gt;HDRDemo Sample&lt;/a&gt;. The HDRLighting Sample is particularly useful. It implements the entire HDR pipeline and the HLSL shader code provided was a great reference point.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-4592537444625241362?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/4592537444625241362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=4592537444625241362' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4592537444625241362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/4592537444625241362'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/implementing-hdr-in-clouds.html' title='Implementing HDR in Clouds'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Ae8yfa48_SM/R95WdwfjA1I/AAAAAAAAAA8/wTpaEwA5NaQ/s72-c/PipelineSmall.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-8953757255992841888</id><published>2008-03-16T21:17:00.006+11:00</published><updated>2008-11-14T07:15:06.348+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Clouds'/><category scheme='http://www.blogger.com/atom/ns#' term='Mulithreading'/><title type='text'>Multithreading in Clouds</title><content type='html'>The Clouds demo posed an interesting problem for me. It required large amounts of CPU power, while at the same time I was finding it difficult to optimise the code any further. The cloud generation and render setup was hitting the CPU hard - and only 50% of my dual core CPU was being utilised.&lt;br /&gt;&lt;br /&gt;While I had dabbled in multithreading before, I'd never applied it to any real-life applications. Clouds was in a unique situation: it was a CPU-intensive application, but had absolutely no requirements regarding latency. So I was free to design the most rediculously input-latency-heavy system I could think of.&lt;br /&gt;&lt;br /&gt;I immediately split the application into 2 threads - simulation and render. Simulation would generate perlin noise, do the day/night cycles, and everything relating to the world itself. The render thread would, well, render. The render thread and the simulation thread are completely decoupled - they can both run at any speed and neither would affect the other.&lt;br /&gt;&lt;br /&gt;I chose a buffered approach to communicate between the two threads. The simulation thread would write information to a buffer, and the render thread would then take that information and use it to draw stuff to the screen. I started off with 3 buffers - one for simulation and two for render. Since the simulation thread was locked to 10hz and the render thread ran as fast as it could, the render thread needed to "fill in the blanks" somehow between each 100ms long timestep. So the render thread uses its two buffers to interpolate between, to produce smooth looking results while the simulation thread writes to the third buffer. Here's what it looks like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://img404.imageshack.us/img404/6794/enginedesignkt5.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178308177609032498" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_Ae8yfa48_SM/R90L2gfjAzI/AAAAAAAAAAs/yec_O_1k87Q/s320/enginedesign.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the problem: this leaves the system open to data starvation. If the simulation thread finishes its simulation before the render thread is done, then the simulation thread has to sit there and wait until the render thread is done with one of its two buffers. However, if the render thread finishes before the simulation thread is done, then the render thread has to sit there and wait for the simulation thread to finish with its current timestep before it can continue interpolating.&lt;br /&gt;&lt;br /&gt;So I added a fourth buffer. The addition of the fourth buffer meant that input latency had grown to a rediculously massive 400-500ms. But that didn't matter, since I didn't have any input that could affect the simulation! The fourth buffer sits in between the simulation thread and render thread, and it donates itself to whoever needs it most. If the simulation thread is done before the render thread, the fourth buffer goes to the simulation thread so it can begin writing the next timestep's data. If the render thread is done before the simulation thread, the fourth buffer goes to the render thread so it can continue interpolating and rendering stuff. So here's the final flow:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://img176.imageshack.us/img176/1136/enginedesign2xw2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5178308375177528130" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_Ae8yfa48_SM/R90MCAfjA0I/AAAAAAAAAA0/K0OQI_JkN8A/s400/enginedesign2.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Because of this buffered approach and the fact that the two threads were completely decoupled, syncronisation overhead is basically nonexistant. However, this system would not be suitable for usage in a real game, since it introduces impossibly large amounts of input latency to the game.&lt;br /&gt;&lt;br /&gt;However, thanks to the &lt;a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=483040"&gt;helpful members of GameDev.Net&lt;/a&gt;, I now have some ideas for how to implementation of this system in a real game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-8953757255992841888?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/8953757255992841888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=8953757255992841888' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8953757255992841888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/8953757255992841888'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/multithreading-in-clouds.html' title='Multithreading in Clouds'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Ae8yfa48_SM/R90L2gfjAzI/AAAAAAAAAAs/yec_O_1k87Q/s72-c/enginedesign.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-1500500359593677713</id><published>2008-03-15T21:58:00.006+11:00</published><updated>2008-03-17T21:53:29.371+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Clouds'/><category scheme='http://www.blogger.com/atom/ns#' term='Perlin Noise'/><title type='text'>Clouds Demo</title><content type='html'>Well, the Clouds demo is pretty much done. The Clouds demo was written to test specific systems in the SolSector Engine. Specifically, the resource management systems, the mesh/material/texture interaction systems and the usage of advanced shaders.&lt;br /&gt;&lt;br /&gt;Here's a youtube video:&lt;br /&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/wcx9xveYAY4"&gt;&lt;br /&gt;   &lt;embed src="http://www.youtube.com/v/wcx9xveYAY4" type="application/x-shockwave-flash" width="425" height="350"&gt;&lt;/embed&gt;  &lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The music is "Primavera" by Ludovico Einaudi. The sprites for the clouds were borrowed from &lt;a href="http://www.gamasutra.com/view/feature/2021/let_there_be_clouds_fast_.php"&gt;this article &lt;/a&gt;at Gamasutra.&lt;br /&gt;&lt;br /&gt;The demo features:&lt;br /&gt;- DirectX10 3D renderer&lt;br /&gt;- Dynamic, perlin-noise generated volumetric clouds&lt;br /&gt;- High Dynamic Range lighting&lt;br /&gt;- Dynamic day/night cycle&lt;br /&gt;- Multithreaded, multi-core optimised design&lt;br /&gt;&lt;br /&gt;It runs at a blazing 20fps on my Core 2 Duo E6600 and Geforce 8800GTS machine. It's completely CPU bound, because of the massive number of sprites I'm dealing with.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Cloud Generation&lt;/strong&gt;&lt;br /&gt;The clouds are generated through simple perlin noise, via &lt;a href="http://libnoise.sourceforge.net/"&gt;libnoise&lt;/a&gt;. Since realism wasn't exactly a key goal here, I just needed a quick and dirty way to generate nice patterns. Remembering the Render&gt;Clouds filter in Photoshop, I turned to perlin noise. &lt;a href="http://en.wikipedia.org/wiki/Perlin_noise"&gt;Perlin noise&lt;/a&gt; is a type of coherent noise defined by &lt;a href="http://en.wikipedia.org/wiki/Ken_Perlin"&gt;Ken Perlin&lt;/a&gt;. It's seen a lot of use all over the place, especially in dynamically-generated content such as these clouds.&lt;br /&gt;&lt;br /&gt;Originally, I had planned to use a more complex simulation to generate more realistic clouds. Initially, I took a look at the works presented by &lt;a href="http://nis-lab.is.s.u-tokyo.ac.jp/~nis/cdrom/pg/PG2001_ryomiya.pdf"&gt;Dobashi et al.&lt;/a&gt; in their whitepaper. They utilised a simplified fluid dynamics simulation model, and during preproduction of the demo I attempted a quick implementation of their simulation. Needless to say, I failed. I didn't have the necessary physics background to understand what they were doing, and the simulation ran too slowly to be of any use anyway. It was at this point that I turned to simpler approaches. I found a&lt;a href="http://www.gamasutra.com/view/feature/2021/let_there_be_clouds_fast_.php"&gt; very informative article &lt;/a&gt;on &lt;a href="http://www.gamasutra.com/"&gt;Gamasutra &lt;/a&gt;regarding the cloud rendering system used in Microsoft Flight Simulator 2004, authored by Niniane Wang of Microsoft. There was also a plethora of information available on &lt;a href="http://www.gamedev.net/"&gt;GameDev.Net&lt;/a&gt;, but it most of it wasn't all too relevant.&lt;br /&gt;&lt;br /&gt;I chose perlin noise because it was simple. However, it was also quite slow. The clouds are essentially just a 128x128 grid of perlin noise - which means a grand total of 16,384 perlin noise samples to regenerate per tick. And it needed to be done on the CPU. I was able to leverage this by implementing a multi-threaded system, which I'll talk about later. All you need to know right now is that, essentially, the generation of the perlin noise came "for free" if you have a dual-core processor or better.&lt;br /&gt;&lt;br /&gt;The perlin noise generated was on a 2D plane, however. To achieve real, proper volume, I'd need to generate unique perlin noise in all 3 dimentions. This would have greatly increased the number of perlin noise samples required per frame (roughly by an order of magnitude). So I faked it - wrote a quick and dirty software bright-pass filter and applied it to the generated 2D perlin noise. This eliminated the darker regions of the noise, and when stacked above each other gave a roughly pyramidal shape for each cloud. To scroll and billow the clouds, it was as simple as adding an offset to the inputs to the perlin noise generator.&lt;br /&gt;&lt;br /&gt;To render the clouds themselves, a simple 128x128x10 sprite grid was placed, and each sprite was made to be more/less transparent, depending on the value of the perlin noise corresponding to each sprite.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'll post more details about the workings of the Clouds demo later on. I'll also post a higher-res version of the demo video, as well as the actual executable if I can find somewhere to host it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-1500500359593677713?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/1500500359593677713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=1500500359593677713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1500500359593677713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/1500500359593677713'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/clouds-demo.html' title='Clouds Demo'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2062085109638480566.post-538901337148858577</id><published>2008-03-09T10:56:00.005+11:00</published><updated>2008-03-17T21:52:50.896+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SolSector Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='Direct3D10'/><title type='text'>Hello World</title><content type='html'>So this is the blogosphere. Not as glamorous as I had imagined.&lt;br /&gt;&lt;br /&gt;A little about me: I'm a hobbyist game developer, and I like to write games in my spare time. I'm fairly well-versed in C++, and I know a little C# on the side. I'm currently working on an ambitious project named "SolSector Engine". I plan for it to be a full-scale, DX10 3D game engine written in C++.&lt;br /&gt;&lt;br /&gt;What's with the name? Well, "SolSector" is actually the name for a future game that I and a friend plan to start someday. And the game needed an engine. So SolSector Engine was born. I usually shorten SolSector Engine to SSE, not to be confused with Intel's Streaming SIMD Extensions. If I mention SSE, I really do mean SolSector Engine and not an instruction set for instruction-level parallelism in CPUs.&lt;br /&gt;&lt;br /&gt;So what is SolSector Engine capable of currently? The engine is still in its early phases of development. However, it's capable of some pretty neat stuff. It features a complete DirectX10 renderer, and systems for the automatic management of resources, sound, input, and windowing. Because it uses Direct3D10, it is Vista-exclusive.&lt;br /&gt;&lt;br /&gt;Right now, I'm writing a small tech demo to test out the various features and subsystems of SolSector Engine. It's called "Clouds", and should be ready in the coming weeks. It won't be particularly pretty or anything, since it is designed to stress-test the engine, not to produce nice graphics (although that's a bonus).&lt;br /&gt;&lt;br /&gt;I'll be making more posts about the Clouds demo and SSE in general later on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2062085109638480566-538901337148858577?l=adtsai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://adtsai.blogspot.com/feeds/538901337148858577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2062085109638480566&amp;postID=538901337148858577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/538901337148858577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2062085109638480566/posts/default/538901337148858577'/><link rel='alternate' type='text/html' href='http://adtsai.blogspot.com/2008/03/hello-world.html' title='Hello World'/><author><name>Sc4Freak</name><uri>http://www.blogger.com/profile/06421803872554731186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
