<?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-3363665146978183397</id><updated>2012-02-16T02:37:52.353-08:00</updated><category term='software quality'/><category term='WOO'/><category term='rules'/><category term='msdn'/><category term='control'/><category term='me'/><category term='java'/><category term='hawken'/><category term='bug'/><category term='egoraptor'/><category term='perl'/><category term='graphics'/><category term='blender'/><category term='games'/><category term='youtube'/><category term='school'/><category term='demo'/><category term='content processor'/><category term='offtopic'/><category term='xact'/><category term='particles'/><category term='audio'/><category term='space combat sim'/><category term='entities'/><category term='collision detection'/><category term='arcade'/><category term='python'/><category term='boom'/><category term='frontend'/><category term='TIGSource'/><category term='art direction'/><category term='optimization'/><category term='clipshow'/><category term='network'/><category term='epic'/><category term='physics'/><category term='requirements'/><category term='dan is dumb'/><category term='project'/><category term='postmortem'/><category term='srs'/><category term='mame'/><category term='architecture'/><category term='lulz'/><category term='battlezone'/><category term='rant'/><category term='PONIES'/><category term='RIM'/><title type='text'>Dan Dan Dan Dan Developing</title><subtitle type='html'>Discussion and ranting about the development of a game as a final-year school project. Followed by discussion and ranting about other stuff now that school is over.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4457665962720615168</id><published>2012-01-12T17:42:00.000-08:00</published><updated>2012-01-12T17:43:55.201-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='egoraptor'/><category scheme='http://www.blogger.com/atom/ns#' term='clipshow'/><category scheme='http://www.blogger.com/atom/ns#' term='PONIES'/><title type='text'>PONIES! And random shite</title><content type='html'>Yes. I admit it. I'm a fan of My Little Pony: Friendship is Magic. After finding a mysterious new trend of pony image macros with a relatively modern art style I got curious. A brief bit of google-fu revealed the show so, out of curiosity, I watched the first episode... then the second, and third, and fourth... and, yeah.&lt;br /&gt;&lt;br /&gt;So here's some random clips I find amusing.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=OPADMGqN1Uk&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=OPADMGqN1Uk&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=h7PGKcikaGY&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=h7PGKcikaGY&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=hWD2Fb4Pneo&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=hWD2Fb4Pneo&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=FbXh7ZipUuQ"&gt;http://www.youtube.com/watch?v=FbXh7ZipUuQ&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=1A6NxMV4Lqo&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=1A6NxMV4Lqo&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And some non-pony bits... just for fun&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=RISJ--pvxmU&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=RISJ--pvxmU&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?feature=endscreen&amp;amp;NR=1&amp;amp;v=jluv2HxFEqs"&gt;http://www.youtube.com/watch?feature=endscreen&amp;amp;NR=1&amp;amp;v=jluv2HxFEqs&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4457665962720615168?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4457665962720615168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2012/01/ponies-and-random-shite.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4457665962720615168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4457665962720615168'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2012/01/ponies-and-random-shite.html' title='PONIES! And random shite'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2907932883671473703</id><published>2012-01-10T20:41:00.000-08:00</published><updated>2012-01-10T20:48:01.756-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software quality'/><category scheme='http://www.blogger.com/atom/ns#' term='frontend'/><category scheme='http://www.blogger.com/atom/ns#' term='srs'/><category scheme='http://www.blogger.com/atom/ns#' term='arcade'/><category scheme='http://www.blogger.com/atom/ns#' term='mame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Making of an Arcade Frontend - Part 2</title><content type='html'>If you haven't read them yet check out &lt;a href="http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-prolog.html"&gt;the prolog&lt;/a&gt; and &lt;a href="http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-part-1.html"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I think it's been &lt;strike&gt;a s&lt;/strike&gt;&lt;strike&gt;ufficient&lt;/strike&gt; &lt;i&gt;ahem&lt;/i&gt; an excessive time since I've posted last...&lt;br /&gt;&lt;br /&gt;During my Christmas vacation I managed to bash out the majority of the features I've wanted to support in my arcade frontend. I had a couple false starts before then. Frustrated, I went with the tried and true "just make the damn thing work" development methodology (aka hacking.)&lt;br /&gt;&lt;br /&gt;Well, I didn't build it quite as haphazardly as that. The idea is to translate the project requirements into some minimal functionality that &lt;b&gt;must&lt;/b&gt; be created for the project to be considered "working." For a small project like this it only takes about 10-30 minutes of effort. For larger projects it takes longer. Most of the time you'll find some features that are independent of each-other. To get the most bang for your buck your best bet is to start working on some feature that a lot of requirements depend on.&lt;br /&gt;&lt;br /&gt;Huh? What?&lt;br /&gt;&lt;br /&gt;I'll give an example. This is taken from the requirements list in &lt;a href="http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-part-1.html"&gt;Part 1&lt;/a&gt; under each requirement is a number of functions that need to be implemented&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Hide the regular Windows front-end.&lt;/div&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Using pygame run in full screen mode&lt;/li&gt;&lt;li&gt;Leave full screen mode before starting a game, re-enter once the game exits&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Allow the user to shut down the computer without exiting to Windows&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Method for responding to user input&lt;/li&gt;&lt;li&gt;Method for confirming user action&lt;/li&gt;&lt;li&gt;Method for invoking windows shutdown&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Allow an administrator to exit to windows&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Method for responding to user input (key-mapped arcade controls)&lt;/li&gt;&lt;li&gt;Clean program shutdown&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Allow rapid selection and launching of games using arcade controls (not keyboard and mouse)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Method for responding to user input (key-mapped arcade controls)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Support launching any game/program, not just MAME&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Scan (something) to create a list of programs that are launchable&lt;/li&gt;&lt;li&gt;When prompted launch a program using information from the list&lt;/li&gt;&lt;/ul&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;Display a preview of the selected game&lt;/li&gt;&lt;ul&gt;&lt;li&gt; Scan (something) to create a list of images associated with games &lt;/li&gt;&lt;li&gt;Method to load images as needed&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Display a list of games that can be played&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Scan (something) to create the list of playable games&lt;/li&gt;&lt;li&gt;Method for distinguishing selected game from others&lt;/li&gt;&lt;li&gt;Method for displaying available games&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Display a marquee for the game... somewhere near the screenshot&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Scan (something) to create a list of images associated with games&lt;/li&gt;&lt;li&gt;Method to load images as needed&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Everything must have an animation&lt;/li&gt;&lt;ul&gt;&lt;li&gt;This means needing an endless update/draw loop for objects&lt;/li&gt;&lt;li&gt;Need a state machine to indicate whether some transition is occurring and what kind&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Alter control-key mappings to support games without configurable controls&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Method to invoke IPAC-2 programmer with some known configuration&lt;/li&gt;&lt;li&gt;Scan (something) to create a list of control configs associated with games &amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;There are a couple things that pop out:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Method to load images as needed&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Scan (something) to create a list of games and things associated with them&lt;/li&gt;&lt;/ul&gt;Of those scanning comes up the most and, more importantly, relates most directly to the purpose of the program which is starting games.&lt;br /&gt;&lt;br /&gt;For my first crack at this I've decided that (something) will be a directory tree containing files called (game)-launcher.cfg which describe playable games. For the sake of organization, since there will likely be well over 100 files, the config files can be in &lt;b&gt;any&lt;/b&gt; directory in the tree.&lt;br /&gt;&lt;br /&gt;What do I want to put in the file:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;The program to start&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Extra information to pass to the program&lt;/li&gt;&lt;li&gt;Controller settings for the game&lt;/li&gt;&lt;li&gt;Where to find game's marquee, screenshot and other image files&lt;/li&gt;&lt;/ul&gt;Now, how do I format the file? I don't want to spend an undue amount of time writing a parser so I could use one of Python's built in parsers. But that still means I need code to convert that to an easily usable datastructure (let's just ignore JSON for now since it slipped my mind at the time) So... how about just making it a Python module. That reduces parsing to one line of code. The file itself simply contains a Python dict with a standardized name and standardized keys.&lt;br /&gt;&lt;br /&gt;First the code to scan for config files:&lt;br /&gt;&lt;pre&gt;def FindAllLaunchables( startDir ):&lt;br /&gt;    outList = []&lt;br /&gt;    dirList = os.listdir( startDir )&lt;br /&gt;    for dir in dirList:&lt;br /&gt;        checkDir = os.path.join( startDir, dir )&lt;br /&gt;        try:&lt;br /&gt;            if os.path.isdir( checkDir ):&lt;br /&gt;                outList.extend( FindAllLaunchables( checkDir ) )&lt;br /&gt;            elif os.path.isfile( checkDir ) and dir.lower().endswith("-launcher.cfg"):&lt;br /&gt;                outList.append( checkDir )&lt;br /&gt;        except WindowsError:&lt;br /&gt;            pass&lt;br /&gt;    &lt;br /&gt;    return outList&lt;/pre&gt;&lt;br /&gt;That's it. The function recursively scans all directories under startDir and, if it finds a configuration file adds its location to an output list which the function returns.&lt;br /&gt;&lt;br /&gt;This bit of code handles reading the configuration file.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;def CreateLaunchers( configFiles ):&lt;br /&gt;    launchers = []&lt;br /&gt;    for launcherConfig in configFiles:&lt;br /&gt;        moduleName = os.path.splitext( launcherConfig )[0].replace( os.path.sep, "_" ).replace( ".", "" ).replace( " ", "_" )&lt;br /&gt;        &lt;br /&gt;        moduleFile = open( launcherConfig )&lt;br /&gt;        try:&lt;br /&gt;            modulePath = os.path.split( launcherConfig )&lt;br /&gt;            module = imp.load_module( moduleName, moduleFile, launcherConfig, ["cfg","rt",imp.PY_SOURCE] )&lt;br /&gt;            launchers.append( config.Launcher( module.LauncherConfig ) )&lt;br /&gt;        finally:&lt;br /&gt;            moduleFile.close()&lt;br /&gt;            del moduleFile&lt;br /&gt;    return launchers&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The meat here is the call to imp.load_module. The imp module exposes some of the guts of Python's import statement and is useful for importing arbitrary files as modules. Notice the config.Launcher object instantiation. The Launcher class will be used to carry out the work of starting up a game based on its configuration along with some other stuff.&lt;br /&gt;&lt;br /&gt;And that's everything! To finish this initial step I stubbed in some code to start up fullscreen mode and to pick up keyboard input. That code is below and makes up the skeleton which the rest of the program will be built around.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;pygame.init()&lt;br /&gt;&lt;br /&gt;# load configuration&lt;br /&gt;configFiles = FindAllLaunchables( search, skip )&lt;br /&gt;launchers = CreateLaunchers( configFiles )&lt;br /&gt;&lt;br /&gt;# startup sequence&lt;br /&gt;screen = SetScreenMode()&lt;br /&gt;pygame.key.set_repeat( 1000, 200 )&lt;br /&gt;pygame.mixer.init()&lt;br /&gt;things = []&lt;br /&gt;&lt;br /&gt;# the main loop!&lt;br /&gt;frameStart = time.clock()&lt;br /&gt;time.sleep( 0.01 ) # XXX: don't want a frame time of 0 when starting&lt;br /&gt;while True:&lt;br /&gt;    frameTime = time.clock() - frameStart&lt;br /&gt;    frameStart = time.clock()&lt;br /&gt;        &lt;br /&gt;    for event in pygame.event.get():&lt;br /&gt;        if event.type == pygame.QUIT or (event.type == KEYDOWN and event.key == pygame.K_F12):&lt;br /&gt;            sys.exit()&lt;br /&gt;        &lt;br /&gt;    for thing in things:&lt;br /&gt;        thing.Update( frameTime )&lt;br /&gt;        thing.Draw( screen )&lt;br /&gt;    pygame.display.flip()&lt;br /&gt;    screen.fill( (0,0,0) )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Whelp, that's all for part 2. I'll have more for you next time! (and since the project is working, next time should be sooner, not later) SetScreenMode isn't all that exciting so I've spared you its details. Notice that with this code we now have the following done.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Using pygame run in full screen mode&lt;/div&gt;&lt;/li&gt;&lt;li&gt;An endless loop to update/draw objects&lt;/li&gt;&lt;li&gt;Method for responding to user input (stub)&lt;/li&gt;&lt;li&gt; Scan (something) to create a list of games and things associated with them&lt;/li&gt;&lt;/ul&gt;Not bad for one blog-entry worth of work eh? &lt;br /&gt;&lt;ul&gt;&lt;li&gt; &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/3363665146978183397-2907932883671473703?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2907932883671473703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2012/01/making-of-arcade-frontend-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2907932883671473703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2907932883671473703'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2012/01/making-of-arcade-frontend-part-2.html' title='Making of an Arcade Frontend - Part 2'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6806563149002682823</id><published>2011-09-02T22:19:00.000-07:00</published><updated>2011-09-02T22:19:41.789-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hawken'/><category scheme='http://www.blogger.com/atom/ns#' term='me'/><category scheme='http://www.blogger.com/atom/ns#' term='epic'/><category scheme='http://www.blogger.com/atom/ns#' term='WOO'/><title type='text'>WOO!</title><content type='html'>Or more precicely &lt;a href="http://www.sandraandwoo.com/"&gt;Sandra and Woo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Oddly enough I found this comic through a banner ad posted on &lt;a href="http://lparchive.org/"&gt;Something Awful's LP archive&lt;/a&gt;. I was reading through the epic that is &lt;a href="http://lparchive.org/Dwarf-Fortress-Boatmurdered/"&gt;Boatmurdered&lt;/a&gt; (no graphic violence, unless you count a white ASCII smiley turning into a red ASCII smiley as violent) I wasn't entirely sure what to expect but the ad interested me so I clicked. And have lost many hours reading through a highly approachable, yet surprisingly mature comic strip. Amusingly, the ad is still running now.&lt;br /&gt;&lt;br /&gt;Initially it's something like Calvin and Hobbes... yet it's nothing like Calvin and Hobbes at the same time. The characters are all older (Sandra's 11, at least at first) and more mature. There's also more budding romance. In any case you should read it. The strip relies a great deal on characterization so some strips don't make much sense unless you know the characters but there's still plenty of strips which stand alone nicely.&lt;br /&gt;&lt;br /&gt;Oh! And I almost forgot! There's a new &lt;a href="http://www.youtube.com/v/BwA03XsKzbY&amp;amp;hd=1"&gt;Hawken trailer&lt;/a&gt; and more &lt;a href="http://www.youtube.com/v/iVa7B1bLv8I&amp;amp;hd=1"&gt;gameplay footage&lt;/a&gt;. I am itching to play this game so badly!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6806563149002682823?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6806563149002682823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/09/woo.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6806563149002682823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6806563149002682823'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/09/woo.html' title='WOO!'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6105293538494450889</id><published>2011-08-19T16:00:00.000-07:00</published><updated>2011-08-19T16:01:47.433-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='lulz'/><title type='text'>Another Gem</title><content type='html'>Posting this from work since I'm doing some boring data uploading crud.&lt;br /&gt;&lt;br /&gt;If you ever find yourself doing this as a programmer/software engineer, please reconsider &lt;span style="font-size: xx-small;"&gt;(your career choice)&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;From: &lt;a href="http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/03_types.htm#29460"&gt;http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/03_types.htm#29460&lt;/a&gt;&lt;br /&gt;&lt;i&gt;&lt;b class="Bold"&gt;Note:&lt;/b&gt; Currently, &lt;code&gt;VARCHAR&lt;/code&gt; is synonymous with &lt;code&gt;VARCHAR2&lt;/code&gt;. However, in future releases of PL/SQL, to accommodate emerging SQL standards, &lt;code&gt;VARCHAR&lt;/code&gt; might become a separate datatype with different comparison semantics. So, it is a good idea to use &lt;code&gt;VARCHAR2&lt;/code&gt; rather than &lt;code&gt;VARCHAR&lt;/code&gt;.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Brilliant! Create a new type because maybe at some point you might want to change the behavior of an existing type at some unspecified time in a vaguely defined future. Apparently the guys at Oracle decided it made less sense to introduce a new type when the need arises &lt;span style="font-size: xx-small;"&gt;(what sane people do)&lt;/span&gt; instead of adding a redundant type right away... just in case. Oh! And make the new type have the old behavior just to conveniently screw up backward compatibility if the original type does change. That's like making "Toy Story" the sequel to "Toy Story 2"... WTF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6105293538494450889?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6105293538494450889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/another-gem.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6105293538494450889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6105293538494450889'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/another-gem.html' title='Another Gem'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-1401139897032047192</id><published>2011-08-17T19:36:00.000-07:00</published><updated>2012-01-12T17:45:10.206-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clipshow'/><category scheme='http://www.blogger.com/atom/ns#' term='boom'/><title type='text'>Fiftith!</title><content type='html'>So, what could be more celebratory than explosions and shooting? Nothing! That's what&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=5HpaWcDX0f4"&gt;http://www.youtube.com/watch?v=5HpaWcDX0f4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=UvvQRIxXGzA&amp;amp;feature=fvsr"&gt;http://www.youtube.com/watch?v=UvvQRIxXGzA&amp;amp;feature=fvsr&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=nY6nm-6eCzM&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=nY6nm-6eCzM&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=9La3Yc2u3NM&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=9La3Yc2u3NM&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=aOx_wHhitqk&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=aOx_wHhitqk&amp;amp;feature=related&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=fOJppJSKG9Y"&gt;http://www.youtube.com/watch?v=fOJppJSKG9Y&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And last but not least. The loading and firing of the main guns of the Iowa class battleship.&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=BJdinQQk1O8&amp;amp;feature=related"&gt;http://www.youtube.com/watch?v=BJdinQQk1O8&amp;amp;feature=related&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-1401139897032047192?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/1401139897032047192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/fiftith.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1401139897032047192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1401139897032047192'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/fiftith.html' title='Fiftith!'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-5796774361956389570</id><published>2011-08-16T20:01:00.000-07:00</published><updated>2011-08-16T20:07:49.022-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software quality'/><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Do not use Java. Ever.</title><content type='html'>While browsing The Daily WTF I was led to &lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4787931"&gt;this gem of a bug in Java.&lt;/a&gt; As if being bought out by Oracle wasn't enough.&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;I doubt the issue will ever be fixed since nobody in the OSS community seems to bother reading documentation for any APIs regardless of who produced them (based on rants from Linus and the above bug). Perhaps if they gave a shit about reading docs they'd give a shit about &lt;i&gt;writing&lt;/i&gt; docs eh? But I digress...&lt;/strike&gt;&lt;br /&gt;&lt;br /&gt;Strike that... generalizations like that aren't fair since the OSS community is large and subject to Sturgeon's Law like any other. And subject to GIFT like any online community.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;JAVA RANT TIME!&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My experience with Java as an application development tool has been, frankly, appalling. AWT and Swing, when combined with NetBeans' visual editor tool, are easily the worst APIs I've ever had to work with.&lt;br /&gt;&lt;br /&gt;A theme I've seen in my mercifully brief experience with Java is that it arbitrarily chooses to do things differently. Not necessarily because it's less verbose (Java code tends to be anything &lt;b&gt;but&lt;/b&gt; verbose) or more flexible (where LISP supposedly cornered the market). Just different... in a manner that's pointless and stupid.&lt;br /&gt;&lt;br /&gt;Imagine if you will that you're designing a data type to store dates. Some methods that might spring to mind would be GetDayOfMonth, GetDayOfWeek, GetMonth, GetYear, GetLengthOfMonth and so on. All fit common use cases for the printing of dates in various fashions used by humans. Using the functions wouldn't require consulting any documentation. So what does Java do? &lt;a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#get(int)"&gt;Mash all of that into one function!&lt;/a&gt; You say that description isn't all that helpful since it doesn't link to relevant information. Fuck you! Find it yourself! &lt;a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#field_summary"&gt;(it's here)&lt;/a&gt;&amp;nbsp;Oh and let's not call the type for storing dates Date or anything like that. Let's call it GregorianCalendar, so that the most obvious common use cases are buttfucked right away.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Most software engineering programs include at least one course on how to make quality code. The fundamental rules of quality can be summed up as follows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make your program's actions and purpose blindingly obvious to the next idiot to see them.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Java's standard library fails even that relatively simple test. Ruby, Python, C#, C, Perl and who knows how many other languages manage to achieve this feat. This is stupid! The only other language which consistently pisses me off like Java is Perl. At least Perl is honest in being a pile of random hacks stacked haphazardly together to scratch some developer itches. Perl is a lazy tool for lazy developers. It fills its niche nicely &lt;span style="font-size: xx-small;"&gt;though arguably Ruby and Python are better languages for the same niche and more besides. &lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Don't use Java. Ever. If your environment is a JVM then try to use a better language that compiles to bytecode. You can find them, JRuby, Groovy, Jython, etc. If you can't do that then at least avoid using Sun's ass-tastic libraries... if Sun has a good library somewhere feel free to use that but my experience makes me doubt the existence of such a beast.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;What's a better language? C#, Python, Ruby, C++ (despite its many flaws), Visual Basic (again despite its many flaws, I think this reflects nicely on how utterly godawful I think Java is)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-5796774361956389570?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/5796774361956389570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/do-not-use-java-ever.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5796774361956389570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5796774361956389570'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/08/do-not-use-java-ever.html' title='Do not use Java. Ever.'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4534080982996282405</id><published>2011-07-31T18:54:00.000-07:00</published><updated>2011-08-01T11:57:33.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software quality'/><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='frontend'/><category scheme='http://www.blogger.com/atom/ns#' term='srs'/><category scheme='http://www.blogger.com/atom/ns#' term='arcade'/><category scheme='http://www.blogger.com/atom/ns#' term='mame'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Making of an Arcade Frontend - Part 1</title><content type='html'>Ah, time to take a break from work and dealing with ASP.NET web applications, continuous integration servers and all that fun (but boring to talk about) crap. Time, for&amp;nbsp;&lt;i&gt;The Making of an Arcade Frontend!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;H'okay. So, like any good software project, my arcade frontend needs a plan. And any good plan starts with a set of goals. A bunch of things the frontend is required to do. In other words, software requirements. Woo! Exciting! Sounds like something out of a college software quality course eh? Well, at least a good software quality course would discuss requirements. After all, it's hard to tell whether your software is "right" or "good' if you don't even know what right or good are.&lt;br /&gt;&lt;br /&gt;There are a few ways of going about making software requirements. You can write up a paragraph of what you want the program to do. Or you could make a checklist of features. Or you could draw a bunch of pictures. Or you could write a formal SRS document. The choice is yours.&lt;br /&gt;&lt;br /&gt;I tend to favor brevity when coming up with goals for my software. It reduces the amount of effort I expend on the requirements stage dealing with contradictory requirements and other general issues. It also helps avoid falling into the trap of writing requirements as a set of instructions on how the program will work; instead of what the program needs to accomplish. If you do fall into the trap of writing a how-to for your program you'll regret it when you find that the design won't work with real code. Good requirements say nothing of how they get achieved. For a large project I tend to go with a short paragraph describing each requirement. A couple sentences does the trick quite nicely. Small projects only really need a set of bullet points. There's no hard and fast rules on what is or isn't descriptive enough for a given project. It really depends on the size of the projects and who is working on it. Practice makes perfect.&lt;br /&gt;&lt;br /&gt;So, what are the requirements for my arcade frontend? Here they are.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hide the regular Windows front-end. It should appear as soon as the computer becomes usable.&lt;/li&gt;&lt;li&gt;Allow the user to shut down the computer without exiting to Windows&lt;/li&gt;&lt;li&gt;Allow an administrator to exit to windows (e.g. to install more games)&lt;/li&gt;&lt;li&gt;Support launching any game/program, not just MAME&lt;/li&gt;&lt;li&gt;Allow rapid selection and launching of games using arcade controls (not keyboard and mouse)&lt;/li&gt;&lt;li&gt;Display a preview of the selected game&lt;/li&gt;&lt;li&gt;Display a list of games that can be played. Preferably in a manner that looks pretty (e.g. like how DDR displays its song list)&lt;/li&gt;&lt;li&gt;Display a marquee for the game... somewhere near the screenshot&lt;/li&gt;&lt;li&gt;Absolutely no hard transitions. Everything must have an animation to go with it&lt;/li&gt;&lt;li&gt;Alter control-key mappings to support games without configurable controls&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;See, nothing all that complicated at all. So, now that I know what I want to do, I need to decide how to do it. That's for another article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4534080982996282405?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4534080982996282405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4534080982996282405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4534080982996282405'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-part-1.html' title='Making of an Arcade Frontend - Part 1'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6401172761993317778</id><published>2011-07-22T21:10:00.000-07:00</published><updated>2011-07-31T18:54:54.960-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frontend'/><category scheme='http://www.blogger.com/atom/ns#' term='arcade'/><category scheme='http://www.blogger.com/atom/ns#' term='mame'/><title type='text'>Making of an Arcade Frontend - Prolog</title><content type='html'>So, if anybody follows my wife's blog you'll have probably heard that I've been building a MAME cabinet. Now I'm not going to talk about the actual physical construction much. If you're interested in that I took plans for the &lt;a href="http://www.koenigs.dk/mame/eng/drawtaitorama.htm"&gt;TaitoRama&lt;/a&gt; cabinet from &lt;a href="http://www.koenigs.dk/mame/eng/index.htm"&gt;Project MAME&lt;/a&gt; as the base. After that I converted the measurements from Metric to Imperial so that I could build it using the tools I have. In the process I also altered the dimensions slightly, increasing the height of the cabinet to exactly 6 feet tall from at the peak.&lt;br /&gt;&lt;br /&gt;The assembly is now done enough for me to start the fun part. Trying it out and tuning the UI.&lt;br /&gt;&lt;br /&gt;The actual working part is a PC running Windows 7 which I put together for about 700 bucks including the monitor and OS. The overkill hardware means I can run stuff other than just MAME smoothly as long as it works well with a 6 button arcade control setup. (Street Fighter 4 is on my shopping list for this thing.) It works, it runs the games I want but... it's still a desktop PC. It doesn't look like an arcade cabinet, and certainly doesn't work with arcade controls.&lt;br /&gt;&lt;br /&gt;I need a frontend to make the cabinet more snazzy. I need something to start up my games that works with the arcade controls, and I need to do something to make the PC look... well... less like a PC. Especially when booting. Every frigging machine out there has the same POST, Starting Windows, Login, Desktop crap; and I don't want to see that when turning on my arcade cabinet.&lt;br /&gt;&lt;br /&gt;To do that, I have turned to the intertubes and found two pieces of the puzzle. The first is &lt;a href="http://www.withinwindows.com/2009/03/15/windows-7-to-officially-support-logon-ui-background-customization/"&gt;a simple registry key&lt;/a&gt; built into Windows 7. Turning it on enables support for a customized login/logout screen, you will only see it when the PC is turning off but it's a start.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.coderforlife.com/projects/win7boot/"&gt;The second piece&lt;/a&gt; is a more fun one. It's a program which allows anyone to create a customized animation for when you start up the computer replacing the usual glowy windows logo. It also lets you replace the captions "Starting Windows" and "(C) Microsoft Corporation" In my case I've changed the captions to "Main Screen Turn On" and some random nonsense. The animation is, well, a screen turning on revealing &lt;a href="http://www.youtube.com/watch?v=qItugh-fFgg"&gt;someone you might know&lt;/a&gt;. Much more fun.&lt;br /&gt;&lt;br /&gt;I haven't found a method to replace the default ASUS POST screen (the image that first appears when the PC turns on) but it should be possible, the OEMs do it after all. However possible firmware hacking can wait, now is the time for getting my games started.&lt;br /&gt;&lt;br /&gt;Now there are lots of arcade frontends out there. Many of them even support multiple emulators, which is good. But they all seem to be geared toward running emulators only. Even if they aren't I don't really care, I'm doing this for fun so I'm going to have fun making my own front-end. It will have my own (or my wife's) graphics, and custom made animations plus as much other pizazz as I wish to jam in there.&lt;br /&gt;&lt;br /&gt;Also it will let me script in extra behind-the-scenes work for running any game I want. For example, if one game has a rigidly defined control scheme (say, Melty Blood) I can reconfigure the arcade controller's driver to work with that game. So, not only can I play awesomeness such as &lt;a href="http://www.youtube.com/watch?v=_qE1NUaKJq4"&gt;Contra&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=6Dw9Euq9GVA"&gt;DoDonPachi&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=E1Ey9OdQXV0"&gt;Donkey Kong&lt;/a&gt; and &lt;a href="http://www.youtube.com/watch?v=FnL0tqeWlhY"&gt;Metal Slug&lt;/a&gt; with MAME, I can also play &lt;a href="http://www.youtube.com/watch?v=jt7OlFTxFJo"&gt;I Wanna be The Guy&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=jt7OlFTxFJo"&gt;Cho Ren Sha 68k&lt;/a&gt;, and other non-emulated games.&lt;br /&gt;&lt;br /&gt;More details to come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6401172761993317778?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6401172761993317778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-prolog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6401172761993317778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6401172761993317778'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/07/making-of-arcade-frontend-prolog.html' title='Making of an Arcade Frontend - Prolog'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-1496494089841982831</id><published>2011-04-22T12:46:00.000-07:00</published><updated>2011-08-19T16:17:38.532-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RIM'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>The Importance of Profiling</title><content type='html'>Ah, profiling. A tool that I've neglected to use for far too long until forced to do so recently at work. No &lt;a href="http://en.wikipedia.org/wiki/Offender_profiling"&gt;I don't mean that&lt;/a&gt;! No &lt;a href="http://en.wikipedia.org/wiki/Racial_profiling"&gt;not that either&lt;/a&gt;!! &lt;a href="http://en.wikipedia.org/wiki/Profiling_%28computer_programming%29"&gt;Profiling&lt;/a&gt; is a tool which is used to examine how long each part of a given program executes to find out why it's slower than molasses in Antarctica.&lt;br /&gt;&lt;br /&gt;A major tool that I support is a test automation framework that supports remotely exercising APIs under test via a scripting language. I had just finished the initial work of porting this system to support testing of some new software when I discovered a problem.&lt;br /&gt;&lt;br /&gt;Under normal circumstances the program can run over one hundred commands per second depending on the time taken by the command itself. An early test however revealed that I was barely managing one or two commands per second. Something was wrong!&lt;br /&gt;&lt;br /&gt;Worse, examining the code provided no obvious answers. There were no poorly made algorithms, no pointless sleeps, no redundant work, nothing. Embarrassingly, this was the first time I've actually used a profiling tool to solve a problem. All other times I've simply muddled around with the code until I found some obvious problem like the ones I mentioned. Whelp, no time like the present, right?&lt;br /&gt;&lt;br /&gt;The tool I was using provided two ways to profile a program's internals. Both involve what's called instrumentation. What that means is the tool generates some extra code in the program for the purpose of measuring your code's behavior. The first profiling method, and by far the simplest, is to count the number of times every function is called. This is helpful in finding candidates for improvement or potential bugs that cause more calls to some code than necessary. The second measures the amount of time spent in each function in addition to the number of times it's called. This is better since it can tell you where your program is getting stuck longest.&lt;br /&gt;&lt;br /&gt;In my case a function which waited for a command stood out as the long runner. Great! Except all it does is call a function to receive data. Digging through the function I found some informational prints, and a call to &lt;a href="http://linux.die.net/man/2/recv"&gt;recv&lt;/a&gt;. Not much to go on. Prints are used in a lot of different places in the program and none of those calls took very long at all, so that's out. Time to put on my google &lt;a href="http://en.wikipedia.org/wiki/Ninja"&gt;Shinobi Shozoku&lt;/a&gt; and find out if there are situations that make recv slow.&lt;br /&gt;&lt;br /&gt;The result? Yes! However it's &lt;a href="http://stackoverflow.com/questions/4428088/reasons-for-a-slow-recv-call"&gt;not recv that's the problem&lt;/a&gt;. It's a little something called &lt;a href="http://en.wikipedia.org/wiki/Nagle%27s_algorithm"&gt;Nagle's Algorithm&lt;/a&gt;, which is part of the TCP/IP protocol stack. It's designed to reduce network traffic by attempting to combining multiple small packets and sending them at once. It does this by holding on to a small packet and waiting for a period of time before sending it, in case more data is coming. Since the tool was designed to minimize bandwidth and be very lightweight in design it would send encoded commands in the form of very small packets, typically a few dozen bytes being large for the tool. Disabling Nagle's Algorithm did the trick.&lt;br /&gt;&lt;br /&gt;Without profiling I might have found the issue in question, but I would have wasted significantly more time either in trial and error. Or worse, not realizing I've made an error, and wasting hours trying to fix something that isn't the problem with negligible improvement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-1496494089841982831?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/1496494089841982831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/importance-of-profiling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1496494089841982831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1496494089841982831'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/importance-of-profiling.html' title='The Importance of Profiling'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4883505473885602982</id><published>2011-04-17T12:05:00.000-07:00</published><updated>2011-04-17T12:05:55.370-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Component Based Architecture</title><content type='html'>This is a relatively old presentation now, but it's a useful one.&lt;br /&gt;&lt;a href="http://cmpmedia.vo.llnwd.net/o1/vault/gdccanada09/slides/marcinchadyGDCCanada.ppt"&gt;http://cmpmedia.vo.llnwd.net/o1/vault/gdccanada09/slides/marcinchadyGDCCanada.ppt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It describes some of the architecture of the game Prototype. It has a very nice description of what goes wrong with simple OO solutions for games when as the scale of a project grows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4883505473885602982?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4883505473885602982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/component-based-architecture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4883505473885602982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4883505473885602982'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/component-based-architecture.html' title='Component Based Architecture'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4369340012291493107</id><published>2011-04-16T18:27:00.000-07:00</published><updated>2011-04-16T20:13:50.585-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hawken'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='TIGSource'/><category scheme='http://www.blogger.com/atom/ns#' term='me'/><category scheme='http://www.blogger.com/atom/ns#' term='boom'/><title type='text'>Looking Forward to this One</title><content type='html'>&lt;p&gt;Well it's been... far too long since the last time I've posted here so I'm going to try to get back into the habit again.&lt;/p&gt;&lt;p&gt;Short story: I'm married, and have been since August 2010, work varies between satisfyingly challenging to insane, I have a pet cat named Doom, and I've barely had any time to do real hobby development work.&lt;/p&gt;&lt;p&gt;I'm going to keep things short so that I'm less likely to get overly lazy and stop posing for months at a time. I'm also not going to restrict my posts to anything in particular... beyond avoiding certain particulars of my job due to NDAs.&lt;/p&gt;&lt;p&gt;During work, I'll spend a smallish amount of time browsing the web. This helps to prevent me from going into mental vapor-lock and keeps me working faster than I would otherwise. I have a few sites I tend to go to that don't take much time to read, and relate just enough to what I'm doing that I don't switch out of the appropriate mindset for coding. One of these sites is the &lt;a href="http://www.tigsource.com/"&gt;TIGsource&lt;/a&gt; blog. This is where I discovered a game that I'm very very excited to see. &lt;a href="http://www.hawkengame.com/"&gt;Hawken&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The game is a mech-sim like game with a pace more on the level of a classic multiplayer deathmatch. Either way, it's been far too long since I got a real fun mech game (years since I got Mechwarrior 4) and Hawken has a very nice feel based on the &lt;a href="http://www.youtube.com/v/udEAEARD-Fo&amp;amp;hd=1"&gt;released gameplay footage&lt;/a&gt;. I also quite like its futuristic high tech shantytown setting. Hope the game turns out as awesome as it looks.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4369340012291493107?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4369340012291493107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/looking-forward-to-this-one.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4369340012291493107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4369340012291493107'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2011/04/looking-forward-to-this-one.html' title='Looking Forward to this One'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8762501604746490841</id><published>2010-07-26T17:43:00.000-07:00</published><updated>2010-07-26T18:24:28.361-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RIM'/><category scheme='http://www.blogger.com/atom/ns#' term='me'/><category scheme='http://www.blogger.com/atom/ns#' term='space combat sim'/><title type='text'>Three Projects... Four Projects... Five Projects!?!</title><content type='html'>Yes, well (conservatively) counting what I'm up to at RIM. The project I'm wrapping up is a particularly fun and rewarding one, creating a tool for providing detailed code coverage tracking for the various testing efforts within the OS Group. Sadly, the details aren't all that exciting. Mostly it's just processing gobs of similar data into an easily queried form. The majority of the work is in the logistics of collecting the data in a way that doesn't interfere with testing and manages to collect as much information is possible given the limitations of the testing environment. My other project(s) relate to some internal OS Group initiatives. I could tell you about them, but then I'd have to kill you ;)&lt;br /&gt;&lt;br /&gt;So that's two...ish. Where's the other three? Well...&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Space Combat Sim&lt;br /&gt;Yup, that thing is still going. Adding bots, improving the graphics, cleaning the code up and generally learning as much about 3D networked games as possible.&lt;/li&gt;&lt;li&gt;A shmup game developed from scratch for XNA on X-Box 360 and PC.&lt;br /&gt;Something simple for building a strong C# codebase that I can port to other projects. Goals here are making a programmable effects system and some decent GUI widgets.&lt;/li&gt;&lt;li&gt;Another shmup, using FlatRedBall&lt;br /&gt;Why? Because screw you! That's why... Actually I figured I'd just start messing around with plugging tools together just since that's normally not the way I make games.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Actually, to go on a boring long monologue...&lt;/p&gt;&lt;p&gt;I have finished only a few game projects, mainly for school. That tends to be because I approach the subject by first building tools and such, then building the game using them. I end up having so much fun making the tools that the project devolves into adding new features and refining code that I lose focus on making the game. Then I get bored and start a new project.&lt;/p&gt;&lt;p&gt;Now, I'm a tools developer professionally I can finally spend all hours of the working day making all sorts of exciting tools for a moderately hardcore development environment. This means that I'm not getting quite the same buzz from making yet more tools at home. So... time to make some fugging games!&lt;/p&gt;&lt;p&gt;Later d00dz! I'll try to keep the interval to next post to less than a month this time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8762501604746490841?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8762501604746490841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/07/three-projects-four-projects-five.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8762501604746490841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8762501604746490841'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/07/three-projects-four-projects-five.html' title='Three Projects... Four Projects... Five Projects!?!'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2875891515566522331</id><published>2010-06-24T18:06:00.000-07:00</published><updated>2010-06-24T18:14:21.916-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RIM'/><category scheme='http://www.blogger.com/atom/ns#' term='TIGSource'/><category scheme='http://www.blogger.com/atom/ns#' term='me'/><title type='text'>Some Inspiration</title><content type='html'>Lately I've been getting most of my coding jollies from my job as a tools developer at RIM. Mostly Python with a nice dose of C, SQL, and other stuff. Mainly fixing some reporting systems that go to external reports seen by management. Plus a dash of code janatorial work since nobody else seemed to be available/willing. After eight months doing solo work it's very nice to be working with a team again.&lt;br /&gt;&lt;br /&gt;Anyway, that's not actually what I wanted to talk about. Today's just a shorty (I have a longer rant about myself coming later.) &lt;a href="http://www.tigsource.com/"&gt;TIGSource&lt;/a&gt; recently posted a couple montages of a huge collection of free, indie games. I've played a few of them (Fraxy, Cave Story, Cho Ren Sha 68k, Prototype 2, Warning Forever, Clean Asia and one or two I can't recall... yea I'm a SHMUP fan) Holy hell there's some awesomeness.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tigsource.com/2010/06/18/425-free-indie-games-in-20-minutes/#comments"&gt;&lt;span style="font-size:130%;"&gt;Check it out!&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-2875891515566522331?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2875891515566522331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/06/some-inspiration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2875891515566522331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2875891515566522331'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/06/some-inspiration.html' title='Some Inspiration'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2805609966266258577</id><published>2010-05-22T16:21:00.000-07:00</published><updated>2010-05-22T16:42:30.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RIM'/><category scheme='http://www.blogger.com/atom/ns#' term='me'/><title type='text'>So, What Now?</title><content type='html'>Well, today I spent a TON of time writing up blogs that I've been meaning to finish for a long time now. Three of them in fact! The first on exporting from Blender to XNA, the second on how the demos for Space Combat Sim went, and the third is a postmortem. But, I haven't talked about what I'm doing now, have I?&lt;br /&gt;&lt;br /&gt;The short answer is that I have a job. In fact, I started my job before my "good demo" which was on May 4th. I'm working as a testing tools developer for Research in Motion. Unless you've been living under a rock for the past few years you've probably heard of their &lt;a href="http://na.blackberry.com/eng/devices/"&gt;flagship product&lt;/a&gt;. Before I started this blog I worked as an intern for RIM over a period of 16 months. I work for the Operating Systems group which is responsible for all of the hardware drivers etc. that make the BlackBerry phone work. The culture of the OS Group, relaxed, friendly and fairly close knit, is what motivated me to return to RIM after finishing school. I'm quite happy working somewhere that I can spend the day working on hard technical problems with minimal political friction then finish the day by hanging around the pub.&lt;br /&gt;&lt;br /&gt;My job now is to maintain and improve tools for automatically testing the Blackberry OS. Obviously I can't go into specific but I will be able to come out with articles on scripting, automation, testing and testing tools in a general sense. On top of the occasional post about work I'll still continue my game development work which means, of coure, more posts on Space Combat Sim and other projects as well.&lt;br /&gt;&lt;br /&gt;Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-2805609966266258577?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2805609966266258577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/so-what-now.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2805609966266258577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2805609966266258577'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/so-what-now.html' title='So, What Now?'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6674478882895508816</id><published>2010-05-10T13:12:00.000-07:00</published><updated>2010-05-22T16:19:52.116-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postmortem'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Space Combat Sim Postmortem</title><content type='html'>In the spirit of continually learning I'm going to do a postmortem of Space Combat Sim as a school project. Don't worry though, this doesn't mean the project is dead. But the priority now is on having fun with it again, instead of busting my ass getting it demo-ready.&lt;br /&gt;&lt;br /&gt;I'm basing my postmortem on those typically found on Gamasutra. If you haven't read one do so, they're &lt;a href="http://www.gamasutra.com/view/feature/4271/postmortem_wayforwards_a_boy_and_.php"&gt;quite eye-opening&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;What Went Right&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;1. Tight, focused scope&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Game projects can be massively complex. Particularly when they're 3d action-oriented online ones :). Most of my early projects started out relatively simply but grew into complex behemoths due to "wouldn't it be cool if" syndrome. For example a simple game where you killed enemies before they could leave the screen evolved into a vertical shmup with procedurally generated levels.&lt;br /&gt;&lt;br /&gt;For Space Combat Sim the scope was set in stone from the beginning. The project would be a multiplayer game combining elements of X-Wing, Quake 3 and Counterstrike. Tools were only to be developed for the game if they were absolutely necessary (ignoring content pipeline extensions only two tools were made, one for creating hit boxes and one for creating effects.)&lt;br /&gt;&lt;br /&gt;With the scope in hand I was able to set out a series of broad goals which defined how the game was to be built from the ground up. These broad goals were converted into a 24 page document describing all of the required features of the game (required for the course.) That was then turned into the detailed list of tasks that needed to be done to produce the game. Making the game was then simply a matter of finishing all of the tasks on the list. Since all time was spent exclusively on those broad goals the amount of wasted effort was minimized.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;2. Continuous integration&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Continuous integration means always having a working version of a project while it's being built. There may be missing features, and if it's a game it may look and play like crap, but it at least exists. One thing that &lt;strong&gt;always&lt;/strong&gt; happens with software projects is scheduling issues. Feature creep, scope creep, unanticipated challenges or whatever, eventually something will cause a project to go off course. Having a working version means that even if the deadling is looming at least &lt;strong&gt;something&lt;/strong&gt; is there for everyone to see.&lt;br /&gt;&lt;br /&gt;In the case of Space Combat Sim, a lot could go wrong. I was challenging myself technically since I hadn't produced a 3D game before, nor had I produced a multiplayer game before. Except for a few occasions I succeeded in this goal. This was very helpful in keeping me from being too ambitious in coding features and forced me to break down overly lofty goals into more doable tasks.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;3. Scrum-like scheduling&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Space Combat Sim used a barebones version of Scrum, albeit with each cycle of development being much longer than specified. By dividing the project into sprints and assigning a set of real deliverables to be completed in each I was able to keep on task. The faculty's imposed limit of about 8 hours per deliverable also helped keep tasks from meandering and getting out of control.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;What Went Wrong&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;1. Not enough time spent getting tools&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;The first four or five months of development time were spent building up the back-end code needed to support the first network session. A huge amount of that could have been saved if I spent that first month just looking at rendering engines and playing with them. No more shader development, effect tool development, etc. etc. in all about two months of work there. Sure, I'd still have to spend time on managing game objects and networking but that was kinda the point of the game. Instead I gave up after about two weeks of looking at tools, honestly, because it was boring.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;2. Working solo&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Especially in combination with making my own tools working solo made the game take a painfully long time to get done. It would have been quite nice if I could have focused more on object management, networking and gameplay while someone else took care of UI, loading, and other backend stuff. With only myself I generally had to focus on every task of game development which tended to result in polish getting short shrift.&lt;br /&gt;&lt;br /&gt;The game's code is poorly documented in places, hacks abound and not all of the visuals that I wanted are in the game.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;3. Continuous integration&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Continuous integration has proven to be a double-edged sword. On one hand, having a working copy of Space Combat Sim all the time was motivating and helped reduce the impact of schedule slippage. On the other hand it made me midjudge whether a particular piece of the game's architecture was actually done or not. The area where this resulted in the most wasted time was in the game's startup sequence. The issue was that, while the game did indeed have space for its menus and loading sequence it wasn't really set up with its final usage in mind.&lt;br /&gt;&lt;br /&gt;Having something that works, and having something that works &lt;em&gt;correctly&lt;/em&gt; are different things. Continuous integration overall has been very useful, but at the same time it can cause one to do something that is expedient and fast rather than the correct solution suitable for the remainder of the project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Overall I'd consider Space Combat Sim a modest success. I met my basic goal, which was to produce a multi-player combat game in space. My more lofty goals of having mission-oriented combat, style etc. weren't met due to time pressures though. The experience has definately been worth while and I learned a lot about actual project development through it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6674478882895508816?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6674478882895508816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/postmortem-whats-next.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6674478882895508816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6674478882895508816'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/postmortem-whats-next.html' title='Space Combat Sim Postmortem'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-3394701026401858244</id><published>2010-05-05T11:50:00.000-07:00</published><updated>2010-05-22T16:20:33.275-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='demo'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='dan is dumb'/><title type='text'>Bad Demo, Good Demo</title><content type='html'>So, here's the final update about Space Combat Sim as a school project. I'll follow up with a postmortem and a bit about what I'm doing in the future.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Bad Demo&lt;/strong&gt;&lt;br /&gt;The first presentation was to faculty and some industry representatives (fortunately their thing seemed to be anything but games.) It was originally going to be in a classroom setting but moved to the lounge in the student life center due to the number of people attending. The lounge, which happened to have one, maybe two, network ports. Both which were in use by other equipment... sigh. Without being able to play with someone all I could do was crash into scenery. Not much of a demo.&lt;br /&gt;&lt;br /&gt;I was able to re-show the project in a lab, with a proper network, but the damage was done. My kingdom for Fraps... and the time (and people) to use it effectively. The fact I didn't have a fallback in case of network failure was a pretty major oversight on my part. Still that last minute venue change was really frustrating.&lt;br /&gt;&lt;br /&gt;The most frustrating issue though was the fact the most vocal representative was most interested in how a project was supposed to make money. The fact he seemed more impressed about a group wearing suits than their actual project (which was quite slick) was particularly rankling. Why in the &lt;em&gt;fuck&lt;/em&gt; are superficial details such as what the presenter is wearing even considered relevant? Caring more about clothing than the product demonstrated is not something to be proud of!&lt;br /&gt;&lt;br /&gt;The impression he left me is that I could have run a pre-rendered video (not a recording of the game) and made up some bullshit about online gaming being worth billions and not been called on the fact I &lt;em&gt;didn't even present a product&lt;/em&gt;. That would have saved a couple months of effort... At least the other members of the panel were willing to ask some technical questions during all the presentations.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Good Demo&lt;/strong&gt;&lt;br /&gt;The second demonstration was at the technology program showcase for the college. This was a 3 hour affair where a large number of people in the various technology programs at the school got to show off their projects. This time a lot more time was given to setup, last time there was a token effort in setting up a router which didn't work at all when used for wired networking. The project was set up on two PCs and running with proper Live accounts. There was some pain as some old bugs managed to magically un-fix themselves, and I didn't actually have the passwords for the Live accounts that were set up for the demo, but that got worked out early on.&lt;br /&gt;&lt;br /&gt;The big lifesaver was having Heather (from Slime Cat Blog) and her sister to demo playing the game while I could talk about what it was and how it worked. They would fly around, shoot at each other, be silly, laugh and generally have fun. This attracted a lot of attention from the various people attending the showcase. It also nicely showed what the project was without me having to go into crazy amounts of detail describing how it worked. I'm glad they were there because a lot of the people coming to see the project weren't gamers.&lt;br /&gt;&lt;br /&gt;By the way, if you're wondering how those photo****d textures turned out; here's a rendering of the three fighter types.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img style="WIDTH: 100%;" src="http://i5.photobucket.com/albums/y178/hwgames/slide-image.jpg" /&gt;&lt;/center&gt;&lt;br /&gt;Not great but still decent for about 2-3 hours per ship I think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-3394701026401858244?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/3394701026401858244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/bad-demo-good-demo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3394701026401858244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3394701026401858244'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/05/bad-demo-good-demo.html' title='Bad Demo, Good Demo'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-1768697576022268811</id><published>2010-04-28T11:21:00.000-07:00</published><updated>2010-05-22T11:48:05.105-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='content processor'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='blender'/><title type='text'>Imporing blender models to XNA as FBX</title><content type='html'>&lt;p&gt;&lt;em&gt;This post was meant for release on April 28th. I've been very busy in May and hadn't had much chance to update until now. Sorry.&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For Space Combat Sim I've been making game models using Blender. It's powerful, it's free and it's got an active development community churning out new versions regularly. &lt;a href="http://www.blender.org"&gt;Check it out.&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Like most modelling programs Blender uses its own file format for model data. XNA projects can't read these files. You normally can only add .X and .FBX files to games using XNA (though there are ways of adding your own model file importers via content pipeline extensions.) Fortunately Blender provides exporters for both X and FBX. I chose FBX due to the readability of the format and the fact the exporter worked more consistently for me.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Exporting from Blender to XNA created two major issues for me. One was ensuring the right material shaders were used. That was handled by writing a simple custom content processor. I simply named materials using "shader-name" which worked nicely. The second issue was more annoying. Blender uses a different co-ordinate system from XNA.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Huh?&lt;/strong&gt; All modelling programs express positions using three numbers representing the object's position on three axes called X, Y and Z. Each axis represents one direction an object can move. In XNA, the X axis goes left to right, the Y axis goes from upward and the Z axis goes out from the screen (backward in the game.) In Blender the Z axis goes upward and the Y axis goes &lt;em&gt;into&lt;/em&gt; the screen.&lt;/p&gt;&lt;p&gt;The result is that if I export a model and use it in XNA as is, it faces downward. Obviously that's a problem. Fortunately XNA provides a nice simple solution.&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/Untitled.jpg" /&gt;&lt;br /&gt;&lt;em&gt;Just rotate it!&lt;/em&gt;&lt;/center&gt;&lt;/p&gt;&lt;p&gt;As you can see here the content processor lets you specify a rotation to be applied to the model before it's used by the game. This takes care of things nicely.&lt;/p&gt;&lt;p&gt;To finish, here's a list of things to watch out for.&lt;ul&gt;&lt;li&gt;Scale. If you don't make your models size consistent with each other you'll need to deal with this in the content processor.&lt;/li&gt;&lt;li&gt;Shaders. By default the model processor in XNA will assign the model a basic shader to render it. Not much good for fancy lighting effects and such.&lt;/li&gt;&lt;li&gt;Orientation. I tended to model my ships facing along the negative Y axis keeping rotation simple. If your models aren't facing straight along an axis importing can be more painful&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/3363665146978183397-1768697576022268811?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/1768697576022268811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/imporing-blender-models-to-xna-as-fbx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1768697576022268811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1768697576022268811'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/imporing-blender-models-to-xna-as-fbx.html' title='Imporing blender models to XNA as FBX'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4160675650129963798</id><published>2010-04-21T19:44:00.001-07:00</published><updated>2010-04-21T20:05:22.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>More Spit and Polish</title><content type='html'>The project demo is in just a few days now. So I'm going crazy with minor bug fixes and polishing to ensure the demo goes well. For example:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The game join menu doesn't crash when no games are available&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The game join menu will poll for new games if none are available&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Beam weapons now do damage when swept through other ships&lt;/li&gt;&lt;br /&gt;&lt;li&gt;All incomplete scenarios are have been disabled&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fighters have photo****ed textures instead of default test patterns&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Minor damge model bugs fixed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Thrusters flicker slowly enough to be noticable&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sound effects fade correctly&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Regarding the photo****: One thing I really wanted to do in this game was give the fighters a nice metallic look. Metal is shiny! But, if I add shininess to the game it gets choppy. Ugh. But I might have a solution. Rust! Patina! etc.&lt;br /&gt;&lt;br /&gt;I want to avoid making the game a rusty-brown shitefest so I'm hoping to go for more of a tarnished silver/brass/bronze/copper look. If, later, I manage to get some decent shininess at decent speed I'll bring back the metal look I wanted originally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4160675650129963798?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4160675650129963798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/more-spit-and-polish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4160675650129963798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4160675650129963798'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/more-spit-and-polish.html' title='More Spit and Polish'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8427450610713696138</id><published>2010-04-17T22:06:00.000-07:00</published><updated>2010-04-21T19:43:22.508-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><category scheme='http://www.blogger.com/atom/ns#' term='battlezone'/><title type='text'>bAAAAAAttlezone</title><content type='html'>The final project for my game development course is roughly done now. Here's a screenshot for postarity.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/battlezonescreenie.jpg" width="100%" height="100%" /&gt;&lt;br /&gt;&lt;br /&gt;The real nasty part was integrating physics into a real project for the first time. I used JigLibX at first but it had several problems. The most severe being a poor selection of constraints, no forcefield support built in, buggy/broken body de-activation and poor performance (especially on the X-Box). I ended up fixing the body de-activation by hacking in a simple iteration through all of the bodies in the system to do the deactivation. No, I'm not submitting this as a patch since it circumvents what &lt;em&gt;should&lt;/em&gt; be a superior method... eventually. I doubt JigLibX is going to see much work however since I remember seeing a post from its author about the creation/release of a new .NET physics library.&lt;br /&gt;&lt;br /&gt;Anyway, I ended up switching to &lt;a href="http://www.bepu-games.com/BEPUphysics/index.html"&gt;BEPU physics&lt;/a&gt; instead. I very strongly reccommend this engine for both its performance, which was quite decent on PC in my project, and its ease of use. I found the integration of BEPU was very simple to carry out and that tasks such as creating composite bodies, constraints etc. was very simple. This is actually somewhat inspiring since I might be able to use this for a future project I've been meaining to do. Sadly, I still have performance issues on the X-Box 360 though the game is playable if I keep the number of objects low.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8427450610713696138?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8427450610713696138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/baaaaaatlezone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8427450610713696138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8427450610713696138'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/baaaaaatlezone.html' title='bAAAAAAttlezone'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7843119202455978037</id><published>2010-04-17T21:10:00.000-07:00</published><updated>2010-04-17T22:20:28.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Spit and Polish</title><content type='html'>Not much to say about the last couple weeks of work. I've added some new visual effects to Space Combat Sim and completed the three different fighter types. At this point the game is somewhat demonstratable but still kinda unstable and needing significant testing to improve its balance. Here's a screenshot of the new effect I added to the game.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/sprint8mid.jpg" width="100%" height="100%" /&gt;&lt;br /&gt;&lt;br /&gt;I've been making a lot of small tweaks to the game of late. My primary objective is to be ready for the project presentation which is coming alarmingly soon. After that I need to have an open demo at the school's Tech@Work event. The most noticable changes to the game are the addition of a semi-working server selection screen, and a lobby screen. These aren't all that interesting to talk about but they produced a spectacular number of bugs during development.&lt;br /&gt;&lt;br /&gt;The other feature in the game is the menu background. Very minor when compared with stuff I talked about earlier but it has an amazing effect on how complete the game feels. All I did was randomly spawn objects (that look exactly the same as the ships but without all of the movement code) and have them move toward and past the camera.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/sprint8menu.jpg" width="100%" height="100%" /&gt;&lt;br /&gt;&lt;br /&gt;Much better than plain old CornflowerBlue eh?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7843119202455978037?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7843119202455978037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/spit-and-polish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7843119202455978037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7843119202455978037'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/04/spit-and-polish.html' title='Spit and Polish'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-5297352266903814782</id><published>2010-03-22T20:10:00.000-07:00</published><updated>2010-03-22T20:13:39.977-07:00</updated><title type='text'>Here's that screenshot</title><content type='html'>A slightly less than pretty picture of more than one person in the game.  I just got the first proper ship type added today.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/sprint7mid2.jpg" width="100%" height="100%" /&gt;&lt;br /&gt;BANZAI!!!1one&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-5297352266903814782?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/5297352266903814782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/heres-that-screenshot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5297352266903814782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5297352266903814782'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/heres-that-screenshot.html' title='Here&apos;s that screenshot'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4942723193717045167</id><published>2010-03-20T16:35:00.001-07:00</published><updated>2010-03-20T17:20:31.169-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Slightly late. Slightly different.</title><content type='html'>So I show up to school on Friday, slightly bleary from a late night, ready to get cracking on the testing the game and... pretty much nobody shows up. In fact, those who did show up were far too busy to help out with testing. The screenshots I promised on Thursday were supposed to be from some multiplayer testing but that didn't work out.&lt;br /&gt;&lt;br /&gt;Today I added point lights to the game. These are nice for lights which come from a location and affect a specific, limited area. Great for more dramatic explosions, shooting and so on. Here's a pic&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/sprint7mid.jpg" width="100%" height="100%" /&gt;&lt;br /&gt;&lt;br /&gt;Lighting in Space Combat Sim is done using some fairly simple math. One topic covered in high-school geometry was the &lt;a href="http://mathworld.wolfram.com/DotProduct.html"&gt;dot product&lt;/a&gt;. The dot product is a scalar product of two vectors. One property of a dot product is that, when it's produced from two &lt;a href="http://mathworld.wolfram.com/UnitVector.html"&gt;unit vectors&lt;/a&gt;, its value is equal to the &lt;a href="http://mathworld.wolfram.com/Cosine.html"&gt;cosine&lt;/a&gt; of the angle between the vectors.&lt;br /&gt;&lt;br /&gt;Why is that useful? Try shining a flashlight on a marble, or ball bearing, or basketball (anything round will do.) Notice that the brightest parts are those that face the light. As the surface of the ball faces away from the light it darkens. If you remember that old high-school math cosine is one for an angle of zero and zero for an angle of ninety degrees.&lt;br /&gt;&lt;br /&gt;Cool. But this still doesn't say how light or dark a surface is... We need one more piece of data. The surface normal. This is a unit vector points straight off of the surface being lit. Let's express the direction of some infinitely far away light source with another vector. Remember what I said in the previous paragraph? The dot product of the two vectors is one if the surface is facing the light perfectly and zero if it isn't facing the light at all. Cool, eh?&lt;br /&gt;&lt;br /&gt;This is the shader code for a directional light. It's a nice stand-in for some sunlight. Notice there's a little bit of extra work here so that it can render eight lights at a time.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float4 outputColor = float4(0, 0, 0, 0);&lt;br /&gt;for(int i = 0; i &lt; GlobalLightCount; i++)&lt;br /&gt;{&lt;br /&gt;    float LightFactor = dot( GlobalLights[i].Vector, input.WorldNormal );&lt;br /&gt;    float4 color = GlobalLights[i].Color * LightFactor;&lt;br /&gt;    outputColor += color;&lt;br /&gt;}&lt;br /&gt;outputColor.a = 1;&lt;br /&gt;return saturate( outputColor ) * tex2D( DiffuseSampler, input.TextureCoord );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now to extend this to point lights.&lt;br /&gt;&lt;br /&gt;Point lights are a little different in that they have a definate location and a limited range. Both of these are fairly easy to deal with. Instead of specifying the direction of the light explicitly we calculate it by finding a unit vector that points from the light source to the object being lit. Cake.&lt;br /&gt;&lt;br /&gt;The range limitation can also be made quite simple if we don't care about being 100% realistic.&lt;br /&gt;Get distance between the light and the object being lit.&lt;br /&gt;Divide that distance by the radius of the light.&lt;br /&gt;Clamp the value to a range between zero and one&lt;br /&gt;Subtract the value from one&lt;br /&gt;&lt;br /&gt;This gives an additional value that we use to adjust the light's intensity based on distance. Here's the resulting HLSL shader code&lt;br /&gt;&lt;pre&gt;float3 lightVector = GlobalLights[7].Vector - input.WorldPosition;&lt;br /&gt;float lightDist = length( GlobalLights[7].Vector - input.WorldPosition );&lt;br /&gt;float3 directionToLight = lightVector / lightDist;&lt;br /&gt;&lt;br /&gt;// falloff light intensity linearly between alpha*radius and radius&lt;br /&gt;float baseIntensity = 1 - saturate( lightDist / GlobalLights[0].Radius );&lt;br /&gt;float diffuseIntensity = saturate( dot( directionToLight, input.WorldNormal ) );&lt;br /&gt;outputColor += GlobalLights[7].Color * baseIntensity * diffuseIntensity;&lt;br /&gt;&lt;br /&gt;outputColor.a = 1;&lt;br /&gt;return saturate( outputColor ) * tex2D( DiffuseSampler, input.TextureCoord );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4942723193717045167?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4942723193717045167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/slightly-late-slightly-different.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4942723193717045167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4942723193717045167'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/slightly-late-slightly-different.html' title='Slightly late. Slightly different.'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7949933480292347038</id><published>2010-03-18T11:20:00.000-07:00</published><updated>2010-03-18T11:50:45.255-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>First killin's</title><content type='html'>All this week I've had the chance to test out and refine the network code of Space Combat Sim. I've also managed to get some of the guys from class to play the game and hash out bugs and glitches. Currently I've only been able to run small test sessions with four players but that's been enough to get a flurry of random bugs that needed fixing.&lt;br /&gt;&lt;br /&gt;Here's an abridged list of SVN commits I've made since my last blog to give you an idea of the number of fixes and tweaks being done. They're in order from newest (yesterday night) to oldest.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Got the game closing down nicely now.&lt;/li&gt;&lt;li&gt;Mostly working game exit sequence... still doesn't unload DynamicTextures yet.&lt;/li&gt;&lt;li&gt;Precess rotation axes when in strafe mode.&lt;/li&gt;&lt;li&gt;Kill beams when its parent dies.&lt;/li&gt;&lt;li&gt;Fix wrong thrusters becoming visible.&lt;/li&gt;&lt;li&gt;Clean up ALL references to a leaving player (fix crash on join after a player quits)&lt;/li&gt;&lt;li&gt;Proper fix for weapon toggle not working on remotes&lt;/li&gt;&lt;li&gt;Minor improvement to weapon switching from remote&lt;/li&gt;&lt;li&gt;Fix scaling in billboard shader&lt;/li&gt;&lt;li&gt;Add state items for targeting, and thrust&lt;/li&gt;&lt;li&gt;Recursively update scene nodes as well as entities. (FIXED THE GLITCH)&lt;/li&gt;&lt;li&gt;Another attempt to fix off-by-one graphical glitch. Didn't work.&lt;/li&gt;&lt;li&gt;Ensure that entities on host will still receive remote input properly.&lt;/li&gt;&lt;li&gt;Don't collect input if using a remote controller&lt;/li&gt;&lt;li&gt;Implement bandwidth usage tracking and some measures to reduce usage&lt;/li&gt;&lt;li&gt;First stab at fixing crash on &gt;2 players at once in game.&lt;/li&gt;&lt;li&gt;Fix wrong name in kill news item&lt;/li&gt;&lt;li&gt;Fix bug where more than one join attempt would cause a crash&lt;/li&gt;&lt;li&gt;Assign gamertag to player slot when initializing on remote.&lt;/li&gt;&lt;li&gt;Remember to dequeue pending notifications after sending them.&lt;/li&gt;&lt;li&gt;Finish up host side of sending player notifications&lt;/li&gt;&lt;li&gt;Implement remote side and part of host side of player notification packet.&lt;/li&gt;&lt;li&gt;Don't actively produce score updates unless hosting the game.&lt;/li&gt;&lt;li&gt;Fix kill detection bug.&lt;/li&gt;&lt;li&gt;First stab at fixing weird off-by-one-frame glitch.&lt;/li&gt;&lt;li&gt;Fix stack overflow in resolving entity creations.&lt;/li&gt;&lt;li&gt;First stab at queuing creations that arrive out of order.&lt;/li&gt;&lt;li&gt;Fix up absurd level of brightness.&lt;/li&gt;&lt;li&gt;Fix impossible to see through HUD&lt;/li&gt;&lt;li&gt;First shot at multipass lighting. Tested with single light&lt;/li&gt;&lt;li&gt;CoalesceDeadEntities called in response to entity destruction packet&lt;/li&gt;&lt;li&gt;Add weapon states to data to be sent.&lt;/li&gt;&lt;li&gt;Make sure criteria for StateItems being sent are updated.&lt;/li&gt;&lt;li&gt;Adjust send criteria to keep bandwidth more sane and keep lag down&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;After all the pain of February this switch from hacking and designing to steady bug fixing and feature creation is a very welcome change of pace. My most satisfying fix was to finally get rid of a bunch of annoying graphical glitches that occured when players would be killed and/or respawned. Their causes are rather boring so I'm not going to bother with any details.&lt;br /&gt;&lt;br /&gt;Screenshots coming tomorrow. I might also talk about how to create a simple radar display.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7949933480292347038?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7949933480292347038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/first-killins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7949933480292347038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7949933480292347038'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/first-killins.html' title='First killin&apos;s'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-3234710642282101095</id><published>2010-03-18T11:09:00.000-07:00</published><updated>2010-04-17T22:13:41.276-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boom'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><category scheme='http://www.blogger.com/atom/ns#' term='battlezone'/><title type='text'>AAAAAA 'Splosions!</title><content type='html'>&lt;div&gt;AAAAAAZone is proceeding nicely. The first project milestone is due tomorrow and what's left to do is implementing enemy AI, which is fun, and force feedback on the gamepad.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;I'm currently using JigLibX to provide physics and collision detection in the game. This is working quite well right now though the lack of documentation is rather irritating. The biggest issue currently is the amount of jittering that occurs with the tank's suspension. That's going to be a pain to work out but that's for later... What's more important is EXPLOSIONS!&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;Yes, EXPLOSIONS! the staple of Michael Bay. They're really simple too. What I do is apply a force to any object within a certain distance of the EXPLOSION!'s position. The force gets weaker as the distance from the EXPLOSION! increases. This is great for sending tanks flying around when shooting them.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;The other trick is applying blast damage. If an EXPLOSION! force is applied to a tank then the tank will take damage. The more force the more damage. Once enough damage is done all of the tank's parts, wheels, axels, guns and such, are detached from eachother.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-3234710642282101095?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/3234710642282101095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/aaaaaa-splosions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3234710642282101095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3234710642282101095'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/aaaaaa-splosions.html' title='AAAAAA &apos;Splosions!'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6607058001049430956</id><published>2010-03-10T13:46:00.000-08:00</published><updated>2010-03-14T12:45:05.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Space Combat Multiplayer</title><content type='html'>Debugging network code for XNA is a huge pain in the arse! Typically when I'm bug hunting I'll place a breakpoint where I roughly think a bug is taking effect, look at the state of any relavent data, then step through the code until the bug manifests. This doesn't work in XNA. If you leave one player or the other player in the debugger for more than about ten seconds their network connection will drop. This means that I have to then reset the game and re-join the session. It gets quite frustrating spending an hour on a simple one line logic error with about ten minutes of that hour being spent actually debugging with the rest being hitting a breakpoint, checking variables for a few second and having the connection drop requiring yet another restart.&lt;br /&gt;&lt;br /&gt;But it was worth it. After much pain multiplayer is now working. I got to show it off to the prof' this Monday. It's still buggy as hell but man, it's satisfying to be able to finally fly around and shoot other people. Even if getting a kill means crashing the program immidiately afterward.&lt;br /&gt;&lt;br /&gt;As promised I'm going to talk about how I've implemented multiplayer so far.&lt;br /&gt;&lt;br /&gt;The game uses a basic client/server architecture. Whoever starts the game acts as the server and has final say on stuff like where players are and who scored what kills. All other players are clients and passively receive data from the server. The only data sent to the server by the clients are an initial "I'm ready to receive data" signal and player input. The data sent to the players dictates stuff like what direction they're facing and how fast they're going.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There is a bit of hairyness here however. The client needs to know stuff like what graphics to use to display the game. If you remember &lt;a href="http://dandandandandev.blogspot.com/2010/02/loading-and-networking.html"&gt;my earlier entry &lt;/a&gt;on multiplayer, XNA allows a game session to have properties, in the form of integers, associated with it. By associating a particular play scenario with a number the client can find out what to load immidiately by checking the properties of the session he's joining.&lt;/p&gt;&lt;p&gt;The whole sequence of joining an active game goes like this&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The client player chooses a server to join&lt;/li&gt;&lt;li&gt;The server notices the new client and creates an object to track what is to be sent to him&lt;/li&gt;&lt;li&gt;The client grabs the scenario number from the server's session properties&lt;/li&gt;&lt;li&gt;The client then runs the &lt;a href="http://dandandandandev.blogspot.com/2010/02/loading-and-networking.html"&gt;normal load sequence&lt;/a&gt;&lt;/li&gt;&lt;li&gt;After loading concludes the client tells the server it's ready to receive data&lt;/li&gt;&lt;li&gt;In response, the server sends the client basic information on all players (their score, team, assigned spawn points and so on)&lt;/li&gt;&lt;li&gt;At this point the client can begin playing. Normally they're waiting to spawn.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Wait... there's no state data sent yet. In fact, if nothing else were sent the player would see nothing except for some background scenery. The magic occurs in the object the server creates to track the data sent to the client.&lt;/p&gt;&lt;p&gt;Each client tracking object has a list of game entities which matter to the clients. The tracking object allows the server to know stuff like whether the client has been informed that the entity exists (or has ceased to exist) and if any state updates are pending. The server sends entity creation data first, updates second and entity destruction data last. The server can also check for certain combinations (e.g. neither creation nor destruction have been sent but both are pending) to save on bandwidth. In the case of the previous example the server would give up on sending either to the client since creation and destruction effectively cancel eachother out.&lt;/p&gt;&lt;p&gt;State updates are a little more complicated than creation and destruction of entities. These are managed by a class called StateItemCollection. StateItems are objects which describe stuff like an entity's position, movement, damage and so on. When some significant change occurs, say the player suddenly accelerates, the associated StateItem flags that interested players should be notified of the change. The client tracking object queries each entity's StateItemCollection for this flag. If any StateItem's flag is set then the server queues up an update for the client. Once the server has queued the update for all relavent players it clears the flag.&lt;/p&gt;&lt;p&gt;There are a couple advantages to using this flagging method. One is that I can allow the server to choose which players receive the state updates. This allows for the server to throttle itself if it's sending too much data, or to skip sending state data that isn't relavent to a particular player. Other advantages lie in the ability to compensate for lag and in merging updates by having later updates replace earlier updates if neither have been sent.&lt;/p&gt;&lt;p&gt;&lt;img style="WIDTH: 100%; HEIGHT: 100%" src="http://i5.photobucket.com/albums/y178/hwgames/Sprint6final.jpg" /&gt;I'll leave you with this screenshot of one (poorly lit) player shooting grey bullets. Notice I have some (glitched) lighting working now :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6607058001049430956?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6607058001049430956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/space-combat-multiplayer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6607058001049430956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6607058001049430956'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/space-combat-multiplayer.html' title='Space Combat Multiplayer'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-268286665085132263</id><published>2010-03-05T20:43:00.000-08:00</published><updated>2010-03-06T09:55:26.324-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><category scheme='http://www.blogger.com/atom/ns#' term='battlezone'/><title type='text'>Another Project</title><content type='html'>I haven't decided how much I'll talk about this one but it is fun. For our Game Development course in my program (Software Engineering at Conestoga College) we have to make a clone of Battlezone using XNA.&lt;br /&gt;&lt;br /&gt;The prof has given a decent amount of leeway in the project to have some fun with it. So, finally I have a chance to try out a physics engine without trying to shoehorn it into a partially completed project.&lt;br /&gt;&lt;br /&gt;I'll probably just update in shorter posts like this one for Battlezone (for now titled AAAAAA Zone due to a naming theme I've been using for the other projects in the Gamedev course)&lt;br /&gt;&lt;br /&gt;Cheers!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-268286665085132263?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/268286665085132263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/another-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/268286665085132263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/268286665085132263'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/another-project.html' title='Another Project'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-1977116013186909010</id><published>2010-03-05T19:30:00.000-08:00</published><updated>2010-03-05T19:32:08.443-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Networking Remark</title><content type='html'>Preview of my next entry:&lt;br /&gt;Debugging network code in XNA Game Studio 3.1 sucks. I spent way more time than I care to think about restarting my game due to stupidity that has nothing to do with actual bugs in the game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-1977116013186909010?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/1977116013186909010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/networking-remark.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1977116013186909010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/1977116013186909010'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/03/networking-remark.html' title='Networking Remark'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-5756418842141195850</id><published>2010-02-20T13:21:00.000-08:00</published><updated>2010-02-20T21:23:26.122-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='particles'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='dan is dumb'/><title type='text'>Particles - Part Deux - The Sequel</title><content type='html'>The Movie - The Game - The... I'll stop now.&lt;br /&gt;&lt;br /&gt;It's been another long hiatus since my last entry where I &lt;a href="http://dandandandandev.blogspot.com/2010/02/loading-and-networking.html://"&gt;discussed a bunch of semi-boring crap about how stuff gets loaded&lt;/a&gt; in Space Combat Sim. Last week (that is the week ending on the 13th) I worked out the protocol for sending the initial game state from one player to another. That part is running somewhat nicely though I've got a bunch of other broken crap to fix before I can really give the details of what I'm doing.&lt;br /&gt;&lt;br /&gt;This week, as you may guess, I'm going to talk about particle effects! Yay! Celebration!!! &lt;a href="http://en.wikipedia.org/wiki/Black_Lagoon"&gt;Peanut butter!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahem. &lt;a href="http://dandandandandev.blogspot.com/2010/01/particle-systems-part-1.html"&gt;Last part &lt;/a&gt;I discussed some basic theory on particle effects and had a pretty screenshot from an old project. Now I was hoping to talk about a clever method I had devised for making really versatile effects with relatively little shader code and some &lt;a href="http://en.wikipedia.org/wiki/High_Level_Shader_Language"&gt;HLSL&lt;/a&gt; snippets. The idea was to store positional, colour and scaling data in the form of textures. Unfortunately this method turned out to be less than workable.&lt;br /&gt;&lt;br /&gt;The idea originated when I was mulling over using cubics, or higher order functions to define the movement and other functions for particles. I figured this would result in a great deal of operations since the function would have to be completely integrated every time a particle gets rendered. At some point I began thinking about such functions in relation to producing complex colour gradients that the particles would run through as they did their thing. I got the idea that if I used a texture I could get a great deal of versatility. By using one texture co-ordinate to represent time and using a random value for the second I could have a particle effect with tens or hundreds of subtly different colour gradients with the hardware doing all of the hard interpolation work practically for free.&lt;br /&gt;&lt;br /&gt;After a little more thought I figured this could be applied to particle positioning. Much in the way a normal map texture's colours represent vectors instead of actual colours I could have a texture whose colours represent a position in space. Depending on implementation this might add expense in the form of providing a normal, tangent and binormal to individual points sprites. Lots of floats but makes for very simple math in aiming a particle effect in a particular direction.&lt;br /&gt;&lt;br /&gt;So, where did this go wrong? A few places. The first, and biggest, was that doing texture lookups in the vertex shader (which is where effects are applied to points sent to the graphics hardware) &lt;a href="http://msdn.microsoft.com/en-us/library/ee418491(VS.85).aspx"&gt;is&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ee418493(VS.85).aspx"&gt;apparently&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ee418495(VS.85).aspx"&gt;unsupported&lt;/a&gt;. If anyone knows a way of doing texture lookups in the vertex shader PLEASE TELL ME. This wasn't enough to prevent me from using the texture to provide fancy colour gradients however. Instead of looking up the colour in the vertex shader I'd simply pass the co-ordinates (time, and a random value) on to the pixel shader. So, it's not a complete loss.&lt;br /&gt;&lt;br /&gt;I have yet to implement the gradient texture due to some stupidity on my part (I used a texture co-ordinate at first which the hardware happily interpolated for me utterly destroying my lookup values.) I can probably salvage it by passing the lookup in a colour semantic since those aren't interpolated. For now I am &lt;a href="http://msdn.microsoft.com/en-us/library/ee418324(VS.85).aspx"&gt;lerp&lt;/a&gt;ing between a randomly selected starting and ending colour.&lt;br /&gt;&lt;br /&gt;What I have now is basically a stripped down version of &lt;a href="http://creators.xna.com/en-CA/sample/particle3d"&gt;Microsoft's Particle3D sample&lt;/a&gt; which I'm mutating into a setup that meets my needs. I'll leave you with a screenshot of my particle effect editor tool to finish.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/Spring6Effected.jpg" width="100%" height="100%" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-5756418842141195850?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/5756418842141195850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/02/particles-part-deux-sequel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5756418842141195850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5756418842141195850'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/02/particles-part-deux-sequel.html' title='Particles - Part Deux - The Sequel'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4135502113749990345</id><published>2010-02-01T19:38:00.000-08:00</published><updated>2010-02-01T20:22:54.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Loading and Networking</title><content type='html'>Soo... here's the blog I promised yesterday.&lt;br /&gt;&lt;br /&gt;I'm not going to bother too much with background information in this entry. The main purpose of the loading sequence (aside from loading, obviously) is to separate the data needed for the player to set up a game (menu text and such) from the data needed to run the game. It also is meant to separate the initial synchronization sequence for players joining the game from the game's proper so the user need not deal with glitches as much.&lt;br /&gt;&lt;br /&gt;In order to simplify content development I made the load sequence as intellegent as possible. When a player chooses a scenario (or a server to join) the game uses a custom content processor to read up data on stuff like team objectives, scoring, spawn points and such. Spawn points are defined such that they always spawn the same type of object. The object type is defined by an entity group type file, the custom content I'm writing about in my &lt;a href="http://dandandandandev.blogspot.com/2010/01/non-trivial-custom-contentprocessor.html"&gt;Custom Content Processor series&lt;/a&gt;, which is referenced in the spawn point. All of the scenario content data is wrapped in a single class.&lt;br /&gt;&lt;br /&gt;With the scenario content loaded the game starts the loading sequence. First a function called GetDependentAssets, a member of the scenario content class, is called. This builds a set of all unique assets referenced by the scenario file. This set lives in the aptly named AssetCollection class.&lt;br /&gt;&lt;br /&gt;Now, this initial list isn't the whole story. Entity groups in particular depend on other assets to render them in the game world. But I don't need to worry about that before loading assets because of some very simple magic built into the load function for entity Asset instances in AssetCollection. An Asset's Load method has access to the AssetCollection's Add function. If an asset in the collection depends on another asset it simply calls the Add function which will append the dependency to the AssetCollection if it's not already there.&lt;br /&gt;&lt;br /&gt;This provides two advantages. First, I can rapidly develop scenarios since I don't have to alter the game's code to ensure all assets referenced by the scenario get loaded, second I have a very clean way of providing feedback to the user of how long the loading sequence will take. As I implied earlier each asset is loaded with an individual Load call. Once the load sequence runs out of assets that require a Load call the basic sequence is done.&lt;br /&gt;&lt;br /&gt;Now what?&lt;br /&gt;Well, if this is the player hosting the game we're good to go. Fire up the network session and let the player play. But if the player is joining an existing game the situation is a bit more hirsute.&lt;br /&gt;&lt;br /&gt;Why? Because, as a joining player I know nothing about the game other than a few simple properties which can be expressed in a small set of 32 bit signed integers. Obviously this isn't much of use, especially since these properties don't really change after starting a game. (As far as I know anyway) I decided that I'll pack the initial scenario selection and its custom scoring/timing/whatever settings. This is enough for the joining player to run the load sequence above without further communication with the game's host.&lt;br /&gt;&lt;br /&gt;After the load though there's a LOT the player needs to know before they can participate in a meaningful manner.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What team is the player on&lt;/li&gt;&lt;li&gt;Where/when will they spawn and as what&lt;/li&gt;&lt;li&gt;Who's on the other team(s)&lt;/li&gt;&lt;li&gt;What's the score, how much time is left etc.&lt;/li&gt;&lt;li&gt;What objects exist in the game, where are they, what do they look like&lt;/li&gt;&lt;li&gt;What objects belong to what players&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, this is where I am now. It's a fun problem to solve and I have a basic protocol thought up but it has yet to be tested. I'll update on it once I've had a chance to test things.&lt;/p&gt;&lt;p&gt;Later doodz&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4135502113749990345?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4135502113749990345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/02/loading-and-networking.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4135502113749990345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4135502113749990345'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/02/loading-and-networking.html' title='Loading and Networking'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-3496981893306612056</id><published>2010-01-31T21:44:00.000-08:00</published><updated>2010-01-31T22:02:18.812-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Don't Worry, I'm Still Here</title><content type='html'>&lt;span style="font-size:180%;"&gt;Sorry about missing last week.&lt;/span&gt;&lt;br /&gt;I'm busy as hell working at the final (though it will probably change still at this stage) game startup sequence. I've got things working nicely now and will have a more detailed update soon. The load sequence is somewhat interesting and I think worthy of a couple paragraphs on this humble blog... later.&lt;br /&gt;&lt;br /&gt;I'm also busy with revamping, and hopefully near-finalizing, the network protocol for the game. I'm giving particular attention to the sequence of events and data transfers that occurs when a player first joins the game.&lt;br /&gt;&lt;br /&gt;If you remember in a previous entry I mentioned how this was the most time-consuming part of an earlier sprint. Given some further (and much briefer thought) I've created a much improved process and am throwing away pretty much all of my old network code in favour of a new solution which should support all of the events that may occur in the final game. All of this I'll write about, in more detail, tomorrow.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Off topic for a second...&lt;/span&gt;&lt;br /&gt;I was visiting my parents earlier today for some delicious chicken and potatoes. I also got to see a bit of my brother's new score in gaming. He's picked up a copy of X3: Terran Conflict. This was a game that I've been moderately interested in acquiring myself. Unfortunately I only got to see a bit of a tutorial mission which was mildly, but irritatingly, broken. My brother was piloting an unarmed freight ship but the instructor, inexplicably, was telling him to blow up debris containers despite being unarmed. Needless to say he had to abort the tutorial at this point... going without any remaining information that could have been provided.&lt;br /&gt;&lt;br /&gt;I hung around for a few more minutes. What I saw implied a large, freeform game universe. I'm strongly reminded of EVE Online, Freelancer and/or (what I've heard of) Privateer. Sadly, I didn't get to see much more since my brother seemed more interested in reading about bread factories than exploring the world.&lt;br /&gt;&lt;br /&gt;However, based on what I've seen I'll definately look to pick up a copy for myself some time. The best part is I don't have to worry about Starforce, SecurROM (sp?) or any other bullshit DRM. I can either get it through Steam or pick up a DRM-free box somewhere. Even if the game turns out to be less cool than I'm thinking it will I'll still be more than happy to support a developer who's willing to not include pseudo-malware in their products.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-3496981893306612056?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/3496981893306612056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/dont-worry-im-still-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3496981893306612056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3496981893306612056'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/dont-worry-im-still-here.html' title='Don&apos;t Worry, I&apos;m Still Here'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4303723820012020662</id><published>2010-01-16T13:03:00.000-08:00</published><updated>2010-01-18T10:03:44.353-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='content processor'/><title type='text'>Non-Trivial Custom ContentProcessor - Part 3</title><content type='html'>&lt;p&gt;So today I'm writing another exciting edition on how I built my custom ContentProcessor for loading game objects. If you've just started reading this series you might want to check out the &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor.html"&gt;Introduction&lt;/a&gt;, &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_15.html"&gt;Part 1&lt;/a&gt; and &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_24.html"&gt;Part 2&lt;/a&gt; first.&lt;/p&gt;&lt;p&gt;When I left off in Part 2 I provided a snippet of code to convert an XML document tree into a set of custom class instances which the game can work with easily. These classes describe how to create a group of in-game entities that make up a starship or other object. However the game makes some assumptions about the data these classes contain which can (and must) be verified by the ContentProcessor.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The group has a root entity. Its parent entity is undefined&lt;/li&gt;&lt;li&gt;There is only one root entity&lt;/li&gt;&lt;li&gt;Entities within the group are only related to eachother, not other groups&lt;/li&gt;&lt;li&gt;Entity properties are valid (notice valid here isn't defined yet, stay tuned :)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If we don't ensure these assumptions are valid then Space Combat Sim will crash when using the processed content. So, the next step that happens is validation and occurs immidiately after all the repeated process shown in Part 2 is finished.&lt;/p&gt;&lt;pre&gt;bool foundParentEntity, foundTopEntity = false;&lt;br /&gt;foreach (Entity entity in Entities)&lt;br /&gt;{&lt;br /&gt;    if (entity.ParentName == "")&lt;br /&gt;    {&lt;br /&gt;        foundTopEntity = true;&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    foundParentEntity = false;&lt;br /&gt;    foreach (Entity parent in Entities)&lt;br /&gt;    {&lt;br /&gt;        if (parent.Name == entity.ParentName)&lt;br /&gt;        {&lt;br /&gt;            foundParentEntity = true;&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (!foundParentEntity)&lt;br /&gt;    {&lt;br /&gt;        throw new ContentLoadException("Entity " + entity.Name + " references non-existant parent " + entity.ParentName);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (!foundTopEntity)&lt;br /&gt;{&lt;br /&gt;    throw new ContentLoadException("Group has no top-level (blank parent) entity!");&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;So, what does this mess do? It verifies that two of the four conditions are true. The outer loop's main purpose is to locate and flag that there is one root entity in the group. The inner loop ensures that every entity (besides the root) has a parent. After the loops is a check to verify that the root was indeed found.&lt;/p&gt;&lt;p&gt;Astute readers might notice a bug in the code above. Circular relationships, e.g. entity A is a child of entity B which is a child of entity A, are not prevented by this procedure. There are a couple ways of dealing with this. The simplest, and most evil, would be to recusively search for the root entity from a given entity. This causes a circular relationship to blow the stack and throw an exception. This can be prevented by making the recursive algorithm build a list of each entity visited as we go up toward the root. If an entity appears in the list more than once then a circular relationship exists. There are also non-recursive ways of doing the same thing which I'll leave as an exercize for the reader.&lt;/p&gt;&lt;p&gt;I decided to omit this step from the game since such errors are rare and are caught in the entity creation tool which you can see in my &lt;a href="http://dandandandandev.blogspot.com/2009/12/apologies-for-delays.html"&gt;article on collision detection&lt;/a&gt;. Currently by crashing horribly, I'll fix that in the future.&lt;/p&gt;&lt;p&gt;Another apparent bug is the lack of testing for non-unique names and for multiple roots. These are both handled earlier. If you remember Part 2 the last part of loading an individual entity block from XML was a call to AddChildEntity.&lt;/p&gt;&lt;pre&gt;foreach (Entity entity in Entities)&lt;br /&gt;{&lt;br /&gt;    if (entity.ParentName.Length == 0 &amp;amp;&amp;amp; parentName.Length == 0)&lt;br /&gt;    {&lt;br /&gt;        throw new ContentLoadException("Multiple top level (blank parent) entities found!");&lt;br /&gt;    }&lt;br /&gt;    if (entity.Name == name)&lt;br /&gt;    {&lt;br /&gt;        throw new ContentLoadException("Multiple instances of " + name + " found!");&lt;br /&gt;    }&lt;br /&gt;    if (entity.Name.Trim().Length == 0)&lt;br /&gt;    {&lt;br /&gt;        throw new ContentLoadException("Found nameless/whitespace named entity!");&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;The actual adding part has been omitted since it isn't that interesting.&lt;/p&gt;&lt;p&gt;With all of this taken care of we still have one item left to validate. The entity's creation parameters. In fact, I have yet to show you how they're loaded. In fact, this is because the main tradeoff is made for thoroughness of validation versus speed and flexibility of coding is made here.&lt;/p&gt;&lt;p&gt;Entities represent a wide range of object types in the game with wildly different rules. Simple objects include stuff such as hull sections which can do little besides be blown up. Others, such as weapons, are much more complex. Parameters are needed to define stuff like timing, positions, orientations and references to other game data. What's worse is that, at the time I was coding this loader, many properties had yet to be determined, stuff like sound effects and so on.&lt;/p&gt;&lt;p&gt;With all of that in mind I decided to err on the side of flexibility. The loader will accept all parameters and ensure that the XML data is valid for the type that is being used to fill the parameter. It will not check if the parameter is used by the game and also won't check if the parameter's type is what is needed by the game. I'll show you how I implemented this validation without adding an excess of validation code to the game itself in Part 4.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4303723820012020662?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4303723820012020662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/non-trivial-custom-contentprocessor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4303723820012020662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4303723820012020662'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/non-trivial-custom-contentprocessor.html' title='Non-Trivial Custom ContentProcessor - Part 3'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-3800774056002408521</id><published>2010-01-09T09:05:00.000-08:00</published><updated>2010-01-09T10:49:24.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='particles'/><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>Particle Systems - Part 1</title><content type='html'>&lt;h1&gt;The Basics&lt;/h1&gt;One of the most fundamental visual effects in games is the particle system. At their simplest a particle system is a collection of objects which can each be described with a single vector quantity. Their position.&lt;br /&gt;&lt;br /&gt;Even these incredibly simple particles can be moderately versatile producing effects such as clouds, fog, plants and so on. Where particles really shine though is when they're &lt;a href="http://www.youtube.com/watch?v=CyAZ2Y7nOTw&amp;amp;NR=1"&gt;allowed to change appearance over time&lt;/a&gt;. The simplest way of doing this is adding one more vector quantity to each particle's description, the particle's velocity. Once each frame we add the particle's velocity to its posision then draw it. This allows particles to simulate simple explosions, fires, smoke, bullets, sparks and so on. As well as clouds, fog and so on...&lt;br /&gt;&lt;br /&gt;How? Just change the values that are assigned to position and velocity when the particles are created.&lt;br /&gt;&lt;br /&gt;&lt;img border="0" alt="Photobucket" src="http://i5.photobucket.com/albums/y178/hwgames/silhouette5.jpg" width="100%" /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;em&gt;Several simple particle systems. From a previous game project of mine&lt;/em&gt;&lt;/p&gt;In this example the blue bullets all launch from the same position but are assigned velocities that cause them to spray outward. The explosions are similar but the velocities point in all directions rather than just to the right. The smoke in the middle appars to drift behind the flame by being created slightly later and given a slower speed. This particular example has a few other variables for particles, namely colour and scale. This saves on art production since a the same clouds can be used for both smoke and fireballs.&lt;br /&gt;&lt;h1&gt;For Space Combat Sim&lt;/h1&gt;&lt;p&gt;Relatively modern 3D hardware supports drawing particles quickly via what is known as &lt;a href="http://msdn.microsoft.com/en-us/library/bb313867.aspx"&gt;point sprites&lt;/a&gt;. Instead of drawing a particle using a &lt;a href="http://nehe.gamedev.net/data/articles/article.asp?article=19#2"&gt;billboard&lt;/a&gt;, which requires four vertices, each particle only requires one vertex. This is great since we can pump out more particles with less data going between main memory and video memory. However this only gets us as far as drawing the very simple particles I mentioned in the beginning. What's worse is as we add variables to particles we increase the amount of data that needs to be sent to the graphics hardware quite rapidly. This gets even worse when varying a particle's properties over time... at least if we do it all on the CPU.&lt;/p&gt;&lt;p&gt;Besides the CPU computers and game consoles also come with another extremely powerful processor capable of chugging through obscene numbers of operations rapidly, the GPU, on the video hardware. This requires some rethinking of how we do some operations like repositioning particles since programming on a GPU is quite different from a general purpose CPU. The GPU is amazingly fast at doing floating point math and vector operations BUT it adds the caveat that changing input data (i.e. changing the vertices that have been passed from the CPU) isn't feasible. I won't go into a huge explanation why but &lt;a href="http://en.wikipedia.org/wiki/Direct3D#Pipeline"&gt;this will help&lt;/a&gt;. The gist of it is that vertices are processed in something like a water pipe. Data can only flow in one direction. You can change it as it flows from one process to another but you can't reverse the flow. (there are ways around this but they're painful and I'm not going to go into them)&lt;/p&gt;&lt;p&gt;So we can't apply velocity to a particle by simply adding to its position repeatedly. What can we do? If you remember your kinematic equations an object's position can be expressed in relation to time with the equasion P&lt;sub&gt;t&lt;/sub&gt; = P&lt;sub&gt;0&lt;/sub&gt;+V*t&lt;/p&gt;&lt;p&gt;Getting the initial position (P0) of a particle to the GPU is easy since that's simply the vertex position for the point sprite. Getting the time and velocity to the GPU are fairly simple but generally require a bit more thought since this is where the particle systems can be made extremely fast and flexible at the same time. I'll leave that for next time however since this entry is already getting rather long.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-3800774056002408521?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/3800774056002408521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/particle-systems-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3800774056002408521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/3800774056002408521'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2010/01/particle-systems-part-1.html' title='Particle Systems - Part 1'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8852354444138714986</id><published>2009-12-29T21:40:00.000-08:00</published><updated>2010-01-09T11:00:26.066-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='xact'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Abstracting XACT 3D Audio</title><content type='html'>Today I worked out the most of the major kinks of getting positional audio working in Space Combat Sim. Well, I guess it's yesterday now since it's 12:45 AM and I finished sound at about 6:00 PM, but I digress.&lt;br /&gt;&lt;br /&gt;My main experience in audio middleware has been working with &lt;a href="http://www.fmod.org/"&gt;FMOD and FMOD Ex&lt;/a&gt;. Both versions of FMOD are extremely powerful yet very easy to use. If I were doing this project using C++ I would not hesitate to use them. But I'm not using C++. Instead I'm using XACT, Microsoft's Cross-platform Audio Creation Tool.&lt;br /&gt;&lt;br /&gt;Overall XACT is somewhat less powerful (no module support, no enviornmental effects, less portable etc.) but it's still reasonably simple to work with and supports the features I'm interested in. Specifically I want to support panning and fading of sound based on the position of the object producing it and I want to support doppler shifting based on how fast the object is moving.&lt;br /&gt;&lt;br /&gt;Despite XACT being simple it proved to not quite be simple enough to use directly with my game objects. Ideally what I'd want to do is be able to associate a sound with an object then start, stop and alter it without having to worry about stuff like which specific sounds should play and so on. Sounds kinda like FMOD Ex's method of dealing with channels and voices independently eh?&lt;br /&gt;&lt;br /&gt;The system I have now is a step in that direction but isn't there yet. For now I'm sticking with it since it works and, for the most part, sounds in Space Combat Sim are really simple so I don't need anything more advanced. My audio class stores an array of some arbitrary number of so-called tracked sounds. Each of these contains a Cue which may or may not be playing, a magic number, and some additional state data.&lt;br /&gt;&lt;br /&gt;When I wish to play a sound that will loop, (and therfore need to be stopped manually,) or that I just want to keep track of because it's long, I specify a flag in my PlaySound function that it should be added to the tracked sounds. PlaySound will then choose a slot in the tracked sound array and replace its cue with whatever I wish to play. The PlaySound function then returns a handle, made by mashing the sound's array index and magic number together. When I decide to stop or alter the sound I simply pass the handle to access it. The index and magic number are extracted and, if the magic number matches the one in the tracked sound, the operation is performed on the Cue object.&lt;br /&gt;&lt;br /&gt;How does this help? Well, by using a handle with a magic number I can eliminate the possibility of accidently messing with a Cue instance that has been squelched due to a more important/louder sound starting. Howzat? The magic number. My audio class is implemented as a GameComponent and is updated every game tick. If it notices a tracked sound whos Cue has stopped for whatever reason it will increment the magic number and null the Cue reference. If an operation were to be attempted on the, now null, Cue nothing would happen since the magic number has been changed. The only requirement here is to keep the number of magic numbers high enough that numbers aren't recycled until after they're no longer in use, otherwise very hard to diagnose bugs could appear.&lt;br /&gt;&lt;br /&gt;Of course now that I've had things working for a while I've learned better ways of doing this which I might try out later. Particularly removing the need to track handles and send position/velocity updates manually from the object playing the sound. But, for now, this is the way things work in the project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8852354444138714986?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8852354444138714986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/abstracting-xact-3d-audio.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8852354444138714986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8852354444138714986'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/abstracting-xact-3d-audio.html' title='Abstracting XACT 3D Audio'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8627640422893292618</id><published>2009-12-28T22:21:00.000-08:00</published><updated>2009-12-28T23:20:28.152-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='collision detection'/><title type='text'>Another Late Entry</title><content type='html'>So here's yet another late entry. Once again, sorry for not keeping to my "at least once a week" schedule. This time I don't really have an excuse since school is finally over for Christmas and New Year.&lt;br /&gt;&lt;br /&gt;What's happened? Well, lessee...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Collision detection is finished&lt;/li&gt;&lt;li&gt;Damage model is finished&lt;/li&gt;&lt;li&gt;Demonstrated the project to the rest of the 3rd year class&lt;/li&gt;&lt;li&gt;Wrote up some extra documentation for the faculty's benefit&lt;/li&gt;&lt;/ul&gt;I ended up ditching one of the &lt;a href="http://dandandandandev.blogspot.com/2009/12/apologies-for-delays.html"&gt;collision test elimination methods I mentioned previously&lt;/a&gt;. Testing the objects in game, &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-corrected"&gt;hierarchically&lt;/span&gt; (i.e. test a group to eliminate all related objects) added complexity that cost more than the benefit of &lt;span id="SPELLING_ERROR_1" class="blsp-spelling-corrected"&gt;eliminating&lt;/span&gt; a few collisions early on. &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-corrected"&gt;Additionally&lt;/span&gt; a &lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;commonish&lt;/span&gt; edge case makes the algorithm design slightly &lt;span id="SPELLING_ERROR_4" class="blsp-spelling-corrected"&gt;hairier&lt;/span&gt; than my initial plan which was to use a &lt;a href="http://en.wikipedia.org/wiki/Breadth-first_search"&gt;breadth-first&lt;/a&gt; search. The AABB of each group of objects on a given level in the hierarchy would be tested, any non-overlapping branches would be eliminated from further testing. Collisions would then be fired for overlaps between objects at the lowest level of the hierarchy. Astute readers might see a potential problem here.&lt;br /&gt;&lt;br /&gt;C&lt;span id="SPELLING_ERROR_5" class="blsp-spelling-error"&gt;ollidable&lt;/span&gt; objects can be attached to other &lt;span id="SPELLING_ERROR_6" class="blsp-spelling-error"&gt;collidable&lt;/span&gt; objects objects across different levels in the entity hierarchy. Because of this collisions can occur at different levels of the hierarchy. In fact collisions can even occur across multiple levels in the entity hierarchy. For example, a fighter's gun can touch another fighters hull and the attached wing. This has to be taken into account. The additional complexity, during my testing, amounted to more CPU work than simply testing all object &lt;span id="SPELLING_ERROR_7" class="blsp-spelling-error"&gt;AABBs&lt;/span&gt; within a spatial hash bucket without grouping them.&lt;br /&gt;&lt;br /&gt;A plausible compromise would be to use the grouping only as a first-pass (i.e. whole group) method of eliminating collisions. This would probably give the best bang for the buck since group parents are easy to find (removing the pain of implementing breadth-first with the current entity storage system, a giant array) and, in the case of capital ships, a LOT of collision tests &lt;span id="SPELLING_ERROR_8" class="blsp-spelling-error"&gt;can be&lt;/span&gt; eliminated at once. For now though, this solution doesn't exist. I'll probably add it when I have the time.&lt;br /&gt;&lt;br /&gt;Speaking of time, the previous sprint (number three for those who care) finished seriously behind schedule with an estimated 50&lt;span id="SPELLING_ERROR_9" class="blsp-spelling-error"&gt;ish&lt;/span&gt; hours of work leftover. For comparison purposes, the faculty expects a bit less than that amount of work to be done &lt;strong&gt;&lt;em&gt;per person per sprint&lt;/em&gt;&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;I am now confronting the pile of unfinished work and attempting to catch up to where I originally wanted to be at the halfway point for the project. This particular sprint, currently set up to occupy my between-semester vacation time, I decided to focus on eye and ear candy in addition to the neglected work from sprint 3.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Positional audio&lt;/li&gt;&lt;li&gt;Particle effects (running on the &lt;span id="SPELLING_ERROR_10" class="blsp-spelling-error"&gt;GPU&lt;/span&gt; no less, though I got the original code/concept from Microsoft's &lt;a href="http://creators.xna.com/en-CA/sample/particle3d"&gt;sample code at the &lt;span id="SPELLING_ERROR_11" class="blsp-spelling-error"&gt;XNA&lt;/span&gt; Community site&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Lighting, at least some basic global lights and hopefully an initial shadowing model&lt;/li&gt;&lt;li&gt;Fixing an amusing, but mysterious, off-by-one-frame bug in the view (or world) matrix of some objects&lt;/li&gt;&lt;/ul&gt;I'll talk about my plans, and completed development, for positional audio and particle effects in the next couple days this week. Perhaps I'll have something screenshot worthy soon...&lt;br /&gt;&lt;br /&gt;I'll also try to find some time to get another Content Pipeline series entry written up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8627640422893292618?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8627640422893292618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/another-late-entry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8627640422893292618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8627640422893292618'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/another-late-entry.html' title='Another Late Entry'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7255354222108253903</id><published>2009-12-05T11:30:00.000-08:00</published><updated>2009-12-05T13:11:41.371-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='collision detection'/><title type='text'>Apologies for the delays</title><content type='html'>As you can see I just released Part 2 of my series on custom content in XNA Game Studio. I think you can also see that I haven't maintained my promised weekly schedule of blog updates.&lt;br /&gt;&lt;br /&gt;It's now nearing the end of the semester and things have gotten quite hectic. The only major issue is that my deadlines are tending to arrive in bunches with assignments coming due all at once so I have to work like mad on non-project stuff then, work like mad on the project until the next wave of assignments hits.&lt;br /&gt;&lt;br /&gt;So, what am I up to now? Glad you asked! I'm working on turning my game into something that actually resembles a game. This means adding the ability to target, shoot and kill other players as well as a small host of other features. How many?&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create teams&lt;/li&gt;&lt;li&gt;Assign players to teams&lt;/li&gt;&lt;li&gt;Create spawn points&lt;/li&gt;&lt;li&gt;Spawn players at spawn points&lt;/li&gt;&lt;li&gt;Timing for when players should spawn&lt;/li&gt;&lt;li&gt;Collision detection&lt;/li&gt;&lt;li&gt;Rules for damaging fighters&lt;/li&gt;&lt;li&gt;Weapon targeting&lt;/li&gt;&lt;li&gt;Kill scoring&lt;/li&gt;&lt;li&gt;Improved network code&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I've finished 1-5 already. They're not thatinteresting to talk about at this point since they don't have much effect at this phase of the project. Most of the real work in getting team assignments, spawning etc. working well will happen in the next couple development phases. What I'm doing now though is feature number 6. And it's a bear of a feature.&lt;/p&gt;&lt;p&gt;Collision detection, in my case, is really about detecting when two objects overlap. A lot of effort is required to figure out whether or not two objects, of any shape or size, are touching or overlapping. So most of my efforts have gone into, first, minimizing the number of objects to be tested, and second, simplifying the math required to find overlaps.&lt;/p&gt;&lt;p&gt;I'm currently using two general tricks to eliminate objects for testing. First, objects are generally defined as groups. For example a fighter isn't just a fighter. It's a hull, wings, thrusters and guns. Capital ships are many pieces of hull and many many guns etc. This allows me to eliminate a large amount of tests very quickly by asking "are these objects close enough to have a chance of overlapping?"&lt;/p&gt;&lt;p&gt;Second is what's known as &lt;a href="http://www.gamedev.net/reference/snippets/features/spatialHash/"&gt;spatial hashing&lt;/a&gt;. This is a way of finding the answer to "are these objects close enough to have a chance of overlapping?" quickly. The basic idea is to take a point in space and assign it to a bucket based on its location. Each bucket represents an area of some size, let's say 50x50x50 units. So if you divide an object's position by 50, you now have the number you need to assign the object to a bucket. All objects that occupy the same bucket get tested for collisions.&lt;/p&gt;&lt;p&gt;Now that we have the objects to test we could just test every object against every other object. e.g. if a bucket has ten objects the result is every object being tested ten times or 100 tests. However what we're really doing is testing &lt;strong&gt;pairs&lt;/strong&gt; of objects. We don't need to test if object A is hitting object B if we already checked object B against object A. We also don't need to test an object against itself. So what do we test?&lt;/p&gt;&lt;p&gt;1. Test the first object against the next nine&lt;br /&gt;2. Test the second object against the next eight&lt;br /&gt;We don't test aginst the first, it's already been tested in step 1&lt;br /&gt;3. Test the third object against the next seven&lt;br /&gt;The previous two steps tested this against the first and second objects&lt;br /&gt;4. Etc.&lt;/p&gt;&lt;p&gt;This means we only need 9 + 8 + ... + 2 + 1, or 45 tests... which do what?&lt;/p&gt;&lt;p&gt;Yes, we're finally at the point of actually doing collision detection. There are two general choices here. First is doing perfect collision detection for the object. This involves a lot of tests for even relatively simple objects, so I'm not doing it. The second choice is to test simplified volumes for overlap. This is what I'm doing.&lt;/p&gt;&lt;p&gt;In my case I'm using two kinds of boxes. First is the &lt;a href="http://en.wikipedia.org/wiki/Axis-aligned_bounding_box"&gt;axis-aligned box&lt;/a&gt; (AABB.) The AABB is useful since I can rapidly eliminate non-collisions by simple value comparisons. The AABB for an object contains the bounding box all objects that are attached as well as the object itself. This helps in eliminating many collisions at once.&lt;/p&gt;&lt;p&gt;This second box is shaped so that it covers the object volume as accurately as possible. This one is used for making the final decision of whether or not two objects are colliding. The math for doing, known as the &lt;a href="http://en.wikipedia.org/wiki/Separating_axis_theorem"&gt;separating axis theorem&lt;/a&gt;, this is somewhat more complex than that for the AABB but not by much. In fact the simple test for the AABB is a special case of the same theorem.&lt;/p&gt;&lt;p&gt; &lt;img src="http://i5.photobucket.com/albums/y178/hwgames/Sprint3Mid.jpg" width="100%" height="100%"/&gt;&lt;/p&gt;&lt;p&gt;This picture shows all of the boxes involved in a collision test (it also shows a tool I created last week for the purpose of setting these boxes up XD) The AABB is orange and the actual collision volume is yellow.&lt;/p&gt;&lt;p&gt;Sorry about the vagueness of the fighter, it's a test model and I haven't set up lighting for the game yet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7255354222108253903?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7255354222108253903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/apologies-for-delays.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7255354222108253903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7255354222108253903'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/12/apologies-for-delays.html' title='Apologies for the delays'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7320610762930884574</id><published>2009-11-24T10:28:00.000-08:00</published><updated>2009-12-28T23:29:18.114-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='content processor'/><title type='text'>Non-Trivial Custom ContentProcessor - Part 2</title><content type='html'>If you're reading this for the first time you might want to check out the &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor.html"&gt;Introduction &lt;/a&gt;and &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_15.html"&gt;Part 1&lt;/a&gt; first.&lt;br /&gt;&lt;br /&gt;The next step taken by the XNA Content Pipeline is to process the data produced by the content importer. This is done by the aptly named ContentProcessor classes. These classes are responsible for pretty much anything that happens between the content being loaded (via ContentImporter or ContentReader which I'll discuss an a later article) and the content being used.&lt;br /&gt;&lt;br /&gt;ContentProcessors are used to massage data into a format usable by an XNA project and/or to load additional content. For example a model processor will load textures and shaders that the model is rendered with. So processors usually run when importing content into a game project or when loading imported content as part of game execution.&lt;br /&gt;&lt;br /&gt;As I mentioned in Part 1, my custom content importer simply converted the raw XML input into a nice tree that can be worked with by the processor (using the .NET System.Xml family of classes.) Now this XML has to be turned into something meaningful to the game. This obviously leaves a lot of work to the content processor.&lt;br /&gt;&lt;br /&gt;As I mentioned before this is the structure of the XML:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Group (document element)&lt;/li&gt;&lt;li&gt;One or more entity elements. Each element defines how it's related to the others. In-game this is used to build an n-tree of entity objects with one entity as the root.&lt;/li&gt;&lt;li&gt;One or more property elements for every entity. The meaning/use of these properties is dependent on the type of entity.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;What we'll do in the processor is iterate through all "entity" elements in the document, read in the data we care about, and add each to a content data class called EntityGroupTypeContent. The code to do this is relatively straigtforward and uninteresting. I'm sure it can be improved but at the time I wrote it my main intention was for it to work.&lt;/p&gt;&lt;pre&gt;outputGroup = new EntityGroupTypeContent();&lt;br /&gt;XmlElement top = input.DocumentElement;&lt;br /&gt;foreach (XmlElement entity in top.GetElementsByTagName("entity"))&lt;br /&gt;{&lt;br /&gt;    // Read in entity attributes (convert from string as needed)&lt;br /&gt;    string name = entity.GetAttribute("name");&lt;br /&gt;    string parentName = entity.GetAttribute("parent");&lt;br /&gt;    string entityType = entity.GetAttribute("type");&lt;br /&gt;    string renderObjectName = entity.GetAttribute("render-object");&lt;br /&gt;    string[] rawPosition = entity.GetAttribute("position").Split(',');&lt;br /&gt;    Vector3 position = new Vector3(Convert.ToSingle(rawPosition[0]),&lt;br /&gt;                                   Convert.ToSingle(rawPosition[1]),&lt;br /&gt;                                   Convert.ToSingle(rawPosition[2]));&lt;br /&gt;&lt;br /&gt;    string[] rawOrientation = entity.GetAttribute("orientation").Split(',');&lt;br /&gt;    Quaternion orientation = new Quaternion(Convert.ToSingle(rawOrientation[0]),&lt;br /&gt;                                            Convert.ToSingle(rawOrientation[1]),&lt;br /&gt;                                            Convert.ToSingle(rawOrientation[2]),&lt;br /&gt;                                            Convert.ToSingle(rawOrientation[3]));&lt;br /&gt;&lt;br /&gt;    // Read entity properties&lt;br /&gt;    Dictionary&lt;string,&gt; properties = new Dictionary();&lt;br /&gt;    foreach (XmlElement property in entity.GetElementsByTagName("property"))&lt;br /&gt;    {&lt;br /&gt;        string propertyName = property.GetAttribute("name");&lt;br /&gt;        EntityGroupPropertyContent propertyData = new EntityGroupPropertyContent(property);&lt;br /&gt;        properties.Add(propertyName, propertyData);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Add the entity&lt;br /&gt;    outputGroup.AddChildEntity(name, parentName, entityType, renderObjectName, position, orientation, properties);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Notice the lack of exception handlers on Convert.ToSingle. If something goes wrong here the exception percolates up to the content builder. When this happens the exception is recorded as a build error in Visual Studio. Also notice the EntityGroupPropertyContent instantiation. It's pretty important but talking about it brings up a lot of discussion irrelevant to this entry. I'll talk more about EntityGroupPropertyContent in Parts 3 and 4.&lt;/p&gt;&lt;p&gt;Next we have to validate the data that was loaded. The game expects the following conditions to be true:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The group has a root entity. Its parent entity is undefined&lt;/li&gt;&lt;li&gt;There is only one root entity.&lt;/li&gt;&lt;li&gt;Entities within the group are only related to eachother, not other groups&lt;/li&gt;&lt;li&gt;Entity properties are valid (notice valid here isn't defined yet, stay tuned :)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Since we didn't verify these conditions in the importer they have to be checked now. This way any errors in the content will be caught by the compiler and show up as build errors. Trying to catch these errors later would result in them crashing the game.&lt;/p&gt;&lt;p&gt;I'll get into validation with Part 3.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7320610762930884574?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7320610762930884574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_24.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7320610762930884574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7320610762930884574'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_24.html' title='Non-Trivial Custom ContentProcessor - Part 2'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8063619811149821480</id><published>2009-11-15T20:56:00.001-08:00</published><updated>2009-11-15T20:56:55.125-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boom'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>BOOM!</title><content type='html'>&lt;a href="http://www.youtube.com/watch?v=sKulBlYqI40&amp;amp;feature=related"&gt;Nobody can resist explosions.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8063619811149821480?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8063619811149821480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/boom.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8063619811149821480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8063619811149821480'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/boom.html' title='BOOM!'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-5794390023574866375</id><published>2009-11-15T13:19:00.000-08:00</published><updated>2009-11-16T09:37:07.172-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='content processor'/><category scheme='http://www.blogger.com/atom/ns#' term='msdn'/><title type='text'>Non-Trivial Custom ContentProcessor - Part 1</title><content type='html'>This is part one on my series on writing a non-trivial custom content processor for XNA Game Studio 3.1. If you want you can read the &lt;a href="http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor.html"&gt;introduction of this series&lt;/a&gt; for useful background information on why I went about writing a content processor.&lt;br /&gt;&lt;br /&gt;Besides the tutorial and samples I mentioned in the introduction &lt;a href="http://msdn.microsoft.com/en-us/library/bb447754.aspx#ID4E5FAC"&gt;MSDN&lt;/a&gt; also has a very nice tutorial on how to create a complete content processor.&lt;br /&gt;&lt;br /&gt;A complete content pipeline extension project consists of the following parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A content importer&lt;/li&gt;&lt;li&gt;A content processor(s)&lt;/li&gt;&lt;li&gt;A content data class(es)&lt;/li&gt;&lt;li&gt;A content writer&lt;/li&gt;&lt;li&gt;A content reader&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Each piece is a distinct step in the process of importing and loading content in your project.&lt;/p&gt;&lt;p&gt;The content importer is a very simple object. All it has to do is open the basic content (image, model, game data etc.) and parse it enough that it's usable by the content processor. Since I originally chose to use XML my importer only needs to open the file as an XML document. If you're using XML you might want to test the document against a DTD to save in sanity checking code in the processor.&lt;/p&gt;&lt;p&gt;Here's the importer:&lt;/p&gt;&lt;p&gt;&lt;pre&gt;using System;&lt;br /&gt;using System.Xml;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using Microsoft.Xna.Framework;&lt;br /&gt;using Microsoft.Xna.Framework.Graphics;&lt;br /&gt;using Microsoft.Xna.Framework.Content.Pipeline;&lt;br /&gt;using Microsoft.Xna.Framework.Content.Pipeline.Graphics;&lt;br /&gt;&lt;br /&gt;// Entity group type specs/annotations are in XML format&lt;br /&gt;using TImport = System.Xml.XmlDocument;&lt;br /&gt;&lt;br /&gt;namespace EntityGroupProcessor&lt;br /&gt;{&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Basic entity group type importer. Entity group types are always in XML. All this does&lt;br /&gt;    /// is load the file.&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    [ContentImporter(".ent", DisplayName = "Entity Group Importer", DefaultProcessor = "EntityGroupTypeProcessor")]&lt;br /&gt;    public class EntityGroupTypeImporter : ContentImporter&lt;timport&gt;&lt;br /&gt;    {&lt;br /&gt;        public override TImport Import(string filename, ContentImporterContext context)&lt;br /&gt;        {&lt;br /&gt;            XmlDocument document = new XmlDocument();&lt;br /&gt;            document.Load(filename);&lt;br /&gt;&lt;br /&gt;            return document;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Notice the line&lt;br /&gt;&lt;pre&gt;[ContentImporter(".ent", DisplayName = "Entity Group Importer", DefaultProcessor = "EntityGroupTypeProcessor")]&lt;/pre&gt;The first part ".ent" specifies the extension of the file that this importer processes. This allows Visual Studio to automatically use this importer when content with the extension of ".ent" is added to the project. The second part specifies the name of the importer as it appears in Visual Studio. The third, and most important part, names the class used to process the output (in this case an XmlDocument instance) in the next step.&lt;br /&gt;&lt;p&gt;The bulk of the code, at least in my case, ends up in the content processor and the content data classes. Stay tuned for Part 2 where I get into the basics of the ContentProcessor and content data classes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-5794390023574866375?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/5794390023574866375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_15.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5794390023574866375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5794390023574866375'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor_15.html' title='Non-Trivial Custom ContentProcessor - Part 1'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7660408320372488756</id><published>2009-11-15T10:55:00.000-08:00</published><updated>2009-11-15T11:01:28.442-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>Neat effect</title><content type='html'>I've been trolling around for information on how I could make a better looking beam weapon. One idea I had was to render them as volumes instead of flat lines. In my research I stumbled across &lt;a href="http://graphicsrunner.blogspot.com/"&gt;Graphics Runner&lt;/a&gt; who has some neat tutorials posted on rendering volumetric effects on his blog. &lt;a href="http://graphicsrunner.blogspot.com/2009/01/volume-rendering-101.html"&gt;Check 'em out&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm likely to not use 3D textures like in these blogs so that I can save on resources. Instead I hope to derive the thickness of a particular section of a beam from the alpha value of that section of beam.&lt;br /&gt;&lt;br /&gt;Stay tuned for followups, and Part 1 of my custom content processor series.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7660408320372488756?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7660408320372488756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/neat-effect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7660408320372488756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7660408320372488756'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/neat-effect.html' title='Neat effect'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2070157657659072686</id><published>2009-11-14T13:52:00.000-08:00</published><updated>2009-11-14T14:20:59.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><category scheme='http://www.blogger.com/atom/ns#' term='content processor'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>Non-Trivial Custom ContentProcessor - Intro</title><content type='html'>The network component is finally done for this sprint. Yay! And I have a project that compiles for the X-Box 360. Yayy!!&lt;br /&gt;&lt;br /&gt;This past week has been interesting so far since I found that my initial solution for batching objects for drawing was impractical when it came to the critical stage of actually doing the batching. So I had to tear it out and start over. The new solution is quite clean and has an added advantage of reducing the amount of data stored for render objects. Only one set of render data is stored no matter how many objects that use it exist. But this change started a cascade of extra changes which has led me to begin developing a custom content processor for XNA.&lt;br /&gt;&lt;br /&gt;I'm working on generalizing the code needed to spawn in-game objects. My original method of loading in-game object data was to load a model and create one in-game object for each mesh that makes the model. The properties of the in-game objects were encoded in the names of the meshes. Initially this worked surprisingly well. The biggest advantage is that I didn't have to spend time on tool development and could focus on getting the game working.&lt;br /&gt;&lt;br /&gt;There are, however, four problems.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No two objects defined in a model can have the same properties (due to mesh names having to be unique)&lt;/li&gt;&lt;li&gt;There's no easy way of creating a deep tree of attached objects (e.g. a capital ship with turrets)&lt;/li&gt;&lt;li&gt;Using names severely limits the number of properties that can be defines&lt;/li&gt;&lt;li&gt;Not all objects need to be models (e.g. beams and bullets)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;My solution is to split off loading of graphics and defining in-game objects. Graphics are loaded and tossed into a pool for later use. Each graphical item has a unique name which can be used to reference it. Once the graphics are loaded the game then has to load information on how to create in-game objects using the graphics.&lt;/p&gt;&lt;p&gt;This is where the ContentProcessor comes in. My current plan is to create a custom XML document which defines a tree of in-game objects and their properties. Each file lists a set of in-game objects to be created. Each object is a single block in the XML file defining the following.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What appearance the object has (references a loaded bit of graphics)&lt;/li&gt;&lt;li&gt;What the object's type is&lt;/li&gt;&lt;li&gt;What the object's reference name is&lt;/li&gt;&lt;li&gt;What the object's parent's reference name is&lt;/li&gt;&lt;li&gt;A set of properties specific to the object's type&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In order to keep the code for the game clean this XML data is to be loaded using a custom ContentProcessor. There are at least some resources out there on the internet including &lt;a href="http://xna.jtmbooks.com/rpgtutorials.html"&gt;this&lt;/a&gt; (tutorial 21, PDF Alert!) and &lt;a href="http://creators.xna.com/en-CA/sample/custommodelclass"&gt;this&lt;/a&gt; which provide some nice sample code. I like the first since it distills the process down to its simplest form. Useful for learning, but it doesn't cover all the nuances I need for what I'm doing.&lt;/p&gt;&lt;p&gt;Stay tuned as I post more details on the content processor.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-2070157657659072686?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2070157657659072686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2070157657659072686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2070157657659072686'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/non-trivial-custom-contentprocessor.html' title='Non-Trivial Custom ContentProcessor - Intro'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4563712310741083451</id><published>2009-11-09T18:50:00.001-08:00</published><updated>2009-11-09T19:23:02.232-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>What to do... what to do... what not to do</title><content type='html'>Earlier in this blog I mentioned that Space Combat Sim is being developed using at least the trappings of the Scrum methodology. I say the trappings because certain aspects of the method don't apply because A, I don't have a team to hold meetings with and B, the Scrum methodology seems to assume a 40 hour week of five 8 hour days. This is great for regular software! I love having 8 hour days. They certainly beat 10 and 12 hour days (grumble grumble.)&lt;br /&gt;&lt;br /&gt;But I digress... one part of Scrum that we do use is the product backlog. It's essentially a glorified to-do list. A huge set of items to be created for the project with estimates for how long they'll take. Work from the list is batched together in units called sprints. The expectation that over the length of the sprint all of the selected tasks are to be done. In the real world I believe sprints are one or two weeks long, in school they're about a month. Anyway, if the to-do list for the sprint isn't empty when the time is up then there's a problem. Fortunately, due to the way Scrum works this problem is noticed as the sprint ends which is usually well before the project is to be delivered. This is the good news.&lt;br /&gt;&lt;br /&gt;The bad news is that, in my case, I have around 40 hours of work left to accomplish in one week. We're expected to put in about 12 hours a week individually. As I hinted before, that's a problem. At this point in the project I can defer some of the work to later sprints if need be. But first, prioritization.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The critical items (not started):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;X-Box 360 support&lt;/li&gt;&lt;li&gt;Beam weapon rendering&lt;/li&gt;&lt;li&gt;Beam weapon test&lt;/li&gt;&lt;li&gt;Capital ship gun turrets (guns which can independently shoot targets)&lt;/li&gt;&lt;li&gt;Targeting cursor/crosshairs&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The incomplete items:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The targeting computer&lt;/li&gt;&lt;li&gt;Weapon status display is working but ugly&lt;/li&gt;&lt;li&gt;Smoke/flames/tracers (barely started)&lt;/li&gt;&lt;li&gt;Sorting/grouping of graphics by how they're to be drawn&lt;/li&gt;&lt;li&gt;The network code (still untested)&lt;/li&gt;&lt;/ul&gt;So now that I have what I want to do I need to decide what I &lt;strong&gt;need&lt;/strong&gt; to do. My primary goal for this phase is to get the fundamentals of multiplayer working and to get the game on the X-Box. I also want there to be enough supporting code done that I can get shooting and killing other players working in the next sprint.&lt;br /&gt;&lt;br /&gt;This leaves:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The network code&lt;/li&gt;&lt;li&gt;X-Box 360 support&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This cuts the amount of work left from ~40 hours to 10.5 hours or so. Much better.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4563712310741083451?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4563712310741083451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/what-to-do-what-to-do-what-not-to-do.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4563712310741083451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4563712310741083451'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/what-to-do-what-to-do-what-not-to-do.html' title='What to do... what to do... what not to do'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-5046229542833960611</id><published>2009-11-08T08:00:00.000-08:00</published><updated>2009-11-08T09:02:10.046-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='control'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>I can haz multiplayer test???</title><content type='html'>Over the last week I've been working on getting the network code implemented for Space Combat Sim. This is one of the most critical parts for the game since without it there's no way for the game to support multiplayer over Live.&lt;br /&gt;&lt;br /&gt;This has turned out to be painful in one place which I didn't expect, the game's rules system. When I first created the game I've been working with a basic startup sequence which creates a bunch of fighters and assigns a local controller (i.e. your X-Box 360 gamepad) to one of them leaving the rest uncontrolled. I originally wanted to create a fairly simple stub and hook joining players to other objects arbitrarily. This didn't work.&lt;br /&gt;&lt;br /&gt;The problem is that when a player joins they initially know nothing of the game's state. This includes which fighter they're supposed to control. If I just assigned one arbitrarily on both sides the results would be inconsistent. Each player would think that the other is attached to a different object. Worse, two players could be trying to control the same object. This meant I had to implement code which runs on the game's host only to assign a player to a specific in-game object. In addition it had to support the player being killed and assigned a new object of (possibly) a different type than before.&lt;br /&gt;&lt;br /&gt;What occurs now is this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The host starts up a game session and starts playing.&lt;/li&gt;&lt;li&gt;Some other player joins the game session&lt;/li&gt;&lt;li&gt;The host notices the joining player and asks the rules system that a new player is in the game. This is where team balancing etc. would occur.&lt;/li&gt;&lt;li&gt;In the mean time the joining player is watching the game without participating.&lt;/li&gt;&lt;li&gt;The host notices that there's a player without a ship (i.e. the joining player.) The host finds an appropriate place to create the player and adds them to the game. In addition the host lets all players know that one of the players has just been assigned a new ship. This is where re-spawn rules would go.&lt;/li&gt;&lt;li&gt;The joining player notices that they've been assigned a ship. Since it doesn't exist on their machine yet they create it and attach their local controller to it. The player is now in the game.&lt;/li&gt;&lt;li&gt;If there were other players they'd also notice a player has been assigned a ship. Since it also doesn't exist for them they'd create it as well.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I've omitted some housekeeping but this is, at least for now, how players joining and being assigned ships is handled. What's left is testing. Since I only have one PC on hand I'll need to do that at school.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-5046229542833960611?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/5046229542833960611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/i-can-haz-multiplayer-test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5046229542833960611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/5046229542833960611'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/i-can-haz-multiplayer-test.html' title='I can haz multiplayer test???'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-913779354834926718</id><published>2009-11-02T18:54:00.000-08:00</published><updated>2009-11-02T19:08:20.043-08:00</updated><title type='text'>Oink</title><content type='html'>Normally in these entries I drone on about some random technical crap that is not terribly interesting but last week I didn't actually do any technical crap... so I don't have anything to talk about.&lt;br /&gt;&lt;br /&gt;Instead, last week, I was down with a nice little case of the swine flu. Not fun... but not the worst disease I've had by any strech however. The only thing that &lt;strong&gt;really&lt;/strong&gt; sucked was the night I didn't get to sleep (and fitfully at that) until about 2:00AM because of an irritating, persistant cough. That and the fact I had not one, but two exams right in the middle of the week I was sick. Oh yeah, that fever was fun too...&lt;br /&gt;&lt;br /&gt;To anyone reading... try to not get the swine flu, it's not the worst flu, but it still sucks.&lt;br /&gt;&lt;br /&gt;I'll be posting about my adventures in getting communication between players working later this week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-913779354834926718?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/913779354834926718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/oink.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/913779354834926718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/913779354834926718'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/11/oink.html' title='Oink'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-6412830726950053595</id><published>2009-10-25T18:05:00.000-07:00</published><updated>2009-10-25T18:38:23.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rules'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>And Now for Something Completely Different</title><content type='html'>For the last week or so I've been working on getting weapons firing. This included a lot of architectural crap which I mentioned previously. Weapons are working quite nicely now, though bullets will keep flying off to infinity forever currently. The other issue are some obnoxious visual defects whose cause is a mystery currently.&lt;br /&gt;&lt;br /&gt;Weapons have some basic rules which govern whether or not they're allowed to fire. First, the gun must have ammunition. Second, the gun must be ready to fire. Every weapon has to rest briefly between shots. In real life this is because it takes time for a new bullet to be loaded into the chamber and for the firing pin to be cocked. Finally, the gun must be cool enough to fire. I decided to take a page from the Mechwarrior games here. Every weapon produces some amount of heat. When this reaches a maximum the player must wait for the weapon to cool off again. Effectively the player's firerate is dramatically cut when the weapon overheats. Between heat, and limited ammo, the player should be encouraged to fire in controlled bursts for maximum damage.&lt;br /&gt;&lt;br /&gt;Today I decided to switch gears. Since this phase is supposed to produce the first multiplayer implementation I started coding in Live support.&lt;br /&gt;&lt;br /&gt;XNA provides network related code in two major chunks. First, GamerServices, which is where most of the Live service code lives. Second is Net, which handles all the grunt work of communication between players.&lt;br /&gt;&lt;br /&gt;The first thing I figured I should tackle is allowing the player to sign in to the Live service. This is done through a program/widget built in to the X-Box 360 called the Guide. As it turns out this required about three lines of code. Two for some setup and the third, which does the real work.&lt;br /&gt;&lt;pre&gt;Guide.ShowSignIn(1, false);&lt;/pre&gt;Seriously! That's all that's needed to fire up the Live signin screen. The 1 states that only one player can be signed in for this game. The second indicates whether only online Live profiles can be used.&lt;br /&gt;&lt;br /&gt;Next task is to get hosting and matchmaking up and running. Thusfar it looks pretty simple. The hard part looks to be the actual work of communication between players.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-6412830726950053595?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/6412830726950053595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/and-now-for-something-completely.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6412830726950053595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/6412830726950053595'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/and-now-for-something-completely.html' title='And Now for Something Completely Different'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-491824407925279345</id><published>2009-10-23T16:03:00.001-07:00</published><updated>2009-10-23T18:06:00.749-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='school'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>This week was umm.... productive?</title><content type='html'>So anybody reading this might recall me saying I might have more information on how the project is going by this week. The good news is that I did get some stuff, namely, guns actually firing bullets, working. The bad news is that's all I got done this week and that was waay back on Sunday/Monday.&lt;br /&gt;&lt;br /&gt;This week has been rather nasty due to other coursework supersceding the main project. Worst was the database course. The project is fairly striaghtforward. Everyone is/was to work in groups of 3-4 people and produce three or four programs that interact with a database tracking the hours of some hypothetical consultants. Very straigtforward... also very boring. The main twists were the intentionally vague specifications and the fact that part of the data, namely the client information (people buying consulting services, not the technobabble meaning of client), had to be on a MySQL database while everything else had to be on SQL Server. That meant a modest amount of extra work. Three/four client applications plus two databases. A nice little chunk of work to disrupt the momentum I had built up for the main project.&lt;br /&gt;&lt;br /&gt;While I was definately productive on the database project (finishing my parts, the server and two of the clients, with about three days of work) I got barely anything done on the main project.&lt;br /&gt;&lt;br /&gt;The work I did do was to fix/improve object composition. That is I can now make an object in-game out of many smaller objects. For example, a fighter can be made of a hull, two wings and two guns. This is all working well now. The underlying code isn't all that interesting to talk about so I'll refrain from doing so.&lt;br /&gt;&lt;br /&gt;As I said before I also got firing bullets working. This really only required the addition of an extra phase in updating the game's state, known as the spawning phase. Any objects that are to be created are placed in a queue. At the end of the update they're created and added to the game. What I want to do now is add a few more rules governing when they're fired. I also need to add the capacity to remove expired objects from the game. Otherwise it will get quickly bogged down by thousands of bullets screaming off into the infinity of deep space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-491824407925279345?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/491824407925279345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/this-week-was-umm-productive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/491824407925279345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/491824407925279345'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/this-week-was-umm-productive.html' title='This week was umm.... productive?'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-4124656199180403690</id><published>2009-10-15T16:29:00.000-07:00</published><updated>2009-10-15T17:14:08.803-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><category scheme='http://www.blogger.com/atom/ns#' term='dan is dumb'/><title type='text'>Another Nasty Bites the Dust</title><content type='html'>As I mentioned in previous blog entries. This development cycle has been far more involved than the first. Mostly due to the fact that it involves a great deal of interdependent parts which all have to be developed at roughtly the same time. In this case I'm getting controls shared across multiple objects, object relationships and physics all working at once to support movement by simulating thrust.&lt;br /&gt;&lt;br /&gt;I've figured out most of the math for the physics but it took several hours of effort to learn the basic math enough to even start. It was a few hours ago that I realized I'm starting to seriously diverge from what I want to be working on. What I'm trying to do is make the game look &lt;em&gt;believable. &lt;/em&gt;I didn't originally intend to make the game accurate. *forehead slap* Out goes the physics, back to the drawing board.&lt;br /&gt;&lt;br /&gt;My new method of simulating thrust is essentially a cheat. I'll just have thrusters &lt;em&gt;appear&lt;/em&gt; to turn on and off in relation to the controls. Instead of simulating the &lt;em&gt;behavior&lt;/em&gt; I'm simulating the &lt;em&gt;appearance&lt;/em&gt; of the thrusters. This is far easier to build saving probably a day or more of work implementing it plus who know how long in getting it to be fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-4124656199180403690?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/4124656199180403690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/another-nasty-bites-dust.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4124656199180403690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/4124656199180403690'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/another-nasty-bites-dust.html' title='Another Nasty Bites the Dust'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-308600180818468471</id><published>2009-10-14T19:40:00.001-07:00</published><updated>2009-10-14T20:06:49.288-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entities'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='control'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>The Second Nastyish Problem</title><content type='html'>I now have the critical part of the batching portion working. Objects are decomposed to their smallest constituant parts which can then be rendered in groups. The actual grouping is still to be done but that's relatively straigtforward. I want to be able to measure how slow/fast I'm making my game's graphics before diving in to some hardcore algorithm hacking.&lt;br /&gt;&lt;br /&gt;The next nasty problem for me to deal with is the issue of getting the game's controls working across multiple objects. For example, the player's fighter can be composed of a hull, a few guns and several thrusters. Input would need to be affect only relevant objects without causing weird side-effects in the others.&lt;br /&gt;&lt;br /&gt;This problem is half solved currently. A single controller object, which is responsible for receiving and processing input from somewhere into actions. Any entity can attach itself to the controller and alter its state based on input from the controller.&lt;br /&gt;&lt;br /&gt;A thruster, for example, can decide whether it should turn on based on whether the controller is saying "turn left" or not. This nicely addresses the issue of getting weapons firing in groups, thrusters firing appropriately and so on.&lt;br /&gt;&lt;br /&gt;The second half of the problem isn't so easily resolved however. I also have to get state data from the enties that are attached to the controller back to the controller so that they can be sent to the network. My other option is to send complete object state data directly from each entity to/from the network, however that defeats the original purpose of the controller.&lt;br /&gt;&lt;br /&gt;An additional problem I didn't quite want to solve this early, but have to, is getting the in-game physics working. This is due to my choice of controlling fighters via believable application of thrust and counter-thrust.&lt;br /&gt;&lt;br /&gt;Plenty to mull over. I probably won't have a solution until the end of this week at earliest.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-308600180818468471?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/308600180818468471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/got-critical-part-of-batching-portion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/308600180818468471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/308600180818468471'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/got-critical-part-of-batching-portion.html' title='The Second Nastyish Problem'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8477594467847535164</id><published>2009-10-13T06:55:00.000-07:00</published><updated>2009-10-13T14:32:20.823-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='dan is dumb'/><title type='text'>First Nastyish Problem Part 2</title><content type='html'>A nice bit of bone-headedness on my part. I spent around 40 minutes scratching my head trying to find how to get the VertexBuffer from ModelMeshPart so I could render it... only to find that it's in the ModelMesh that owns it. D'oh.&lt;br /&gt;&lt;br /&gt;It really helps to look in the right place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8477594467847535164?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8477594467847535164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/first-nastyish-problem-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8477594467847535164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8477594467847535164'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/first-nastyish-problem-part-2.html' title='First Nastyish Problem Part 2'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-8756024802930008066</id><published>2009-10-12T18:25:00.000-07:00</published><updated>2009-10-12T19:21:51.048-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>First Nastyish Problems</title><content type='html'>Now that the first phase of getting the basics up and running is done I'm starting to confront the nastier issues of getting this project to resemble a game that might, some day, be fun to play. Not to mention fleshing out the game's internals so they function as I originally intended them to.&lt;br /&gt;&lt;br /&gt;The focus of the effort for the next couple days is on getting the graphics system batching objects to be rendered correctly.&lt;br /&gt;&lt;br /&gt;The concept behind batching is to group together all similar objects to the video card in one big chunk. The hard part is that my graphics system is meant to contain very different types of objects (e.g. both 2D particles and 3D models) in a particular scene.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Technical crap below&lt;/strong&gt;&lt;br /&gt;My solution is to build two interfaces. The first, known as IRender, represents a complete drawable thing, for example a laser cannon on a fighter. This exposes objects which have the second interface, IRenderPart. These represent a piece of the whole object which has its own special appearance. For example an IRenderPart could be a glowing tip on the laser cannon and a second could be the actual body of the cannon.&lt;br /&gt;&lt;br /&gt;The IRenderPart is the critical piece for batching. The IRenderPart exposes instructions on how it is to be drawn. The rendering enging groups all IRenderParts with similar instructions and draws them all at once. This, in theory, saves time used in sending different sets of instructions to the game console's video hardware since each set of instructions only needs to be sent once.&lt;br /&gt;&lt;br /&gt;The big advantage of using interfaces is that they allow the graphics engine to see only the information it cares about to group the objects without having to worry about what, exactly, those objects are. This addresses the nasty issue of handling the variety of visible objects in the game that need to be drawn.&lt;br /&gt;&lt;strong&gt;End of technical crap&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Now it's down to implementing the changes. I'm approximately 25% done. In addition I need to implement a performance measuring harnass in the game so that I can perform adjustments to the game's code and know exactly what effects they have on the game's speed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-8756024802930008066?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/8756024802930008066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/first-nastyish-problems.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8756024802930008066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/8756024802930008066'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/first-nastyish-problems.html' title='First Nastyish Problems'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2943509095282030765</id><published>2009-10-08T14:00:00.000-07:00</published><updated>2009-10-08T16:35:42.095-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>The Cockpit</title><content type='html'>Today I'm going to talk about the cockpit in the game as it is right now. When you're playing you see everything as if you're the pilot sitting in the cockpit of a starfighter. What I hope to do is display all information relating to the state of a player's fighter as part of the fighter's cockpit. This dictated that the cockpit be one of the first things to be coded since it will be critically important to the player's in-game experience. The fundamentals (code-wise) are there now but they're not much to look at currently since I don't have much of any artwork done.&lt;br /&gt;&lt;img src="http://i5.photobucket.com/albums/y178/hwgames/Sprint1Final.jpg" alt="Cockpit test" width="100%"/&gt;&lt;br /&gt;&lt;br /&gt;I was motivated to do the cockpit this way by a pet peeve I have with space combat games like, for example, Freespace. &lt;em&gt;The in-flight displays are just sprites, they're not part of the fighter!&lt;/em&gt; While this is primarily an aesthetic complaint it's something I feel is a major detriment to the immersion factor of games that often purport themselves as simulators.&lt;br /&gt;&lt;br /&gt;There are a number of challenges with building the game's displays this way. Foremost is layout. The displays need to be placed such that they make sense and all of the information on them can be read easily. Also I need to decide how many displays there are, and what each should contain. Finally, I need to decide if there are to be any controls which change a display's appearance, for example switching between text and visual diagnostics. And, just for extra spice, the layout must fit completely within the "title safe" area which is the area visible on all TVs. If the displays don't fit then they'll be cut off for some players on the X-Box. Oops.&lt;br /&gt;&lt;br /&gt;Currently I'm drawing inspiration from the F-16 fighter for a general layout of the cockpit. The F-16 features a HUD and three large displays for various tactical data.&lt;br /&gt;&lt;img alt="F-16 Cockpit" src="http://i5.photobucket.com/albums/y178/hwgames/f16_cockpit_image.jpg" width="100%" /&gt;&lt;br /&gt;In the game the cockpit will be somewhat similar. The HUD will display navagational and targeting data. The left screen will display sensory data and weapon status (e.g. ammo.) The right screen will display diagnostic data (i.e. what is, and what is not damaged.) The central screen will display tactical data. Additional information, such as score, is still displayed as text and graphics on the screen outside of game space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-2943509095282030765?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2943509095282030765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/cockpit.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2943509095282030765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2943509095282030765'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/cockpit.html' title='The Cockpit'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-9052686149008896770</id><published>2009-10-02T18:40:00.000-07:00</published><updated>2009-10-02T19:15:40.723-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><category scheme='http://www.blogger.com/atom/ns#' term='art direction'/><title type='text'>Perhaps we have a muse</title><content type='html'>The first few builds of the project have been finished. Nothing too interesting to look at but you can fly around in space and the cockpit (but none of the information it should display) renders. After some initial testing with the demos I've downloaded I've decided that the Nuclex framework fits my needs better than Titanium XNA. It's a much more minimal product in that it's more of a toolbox than a game engine but the quality of those tools is excellent. Props to you &lt;a href="http://cygon.nuclex.org/author/cygon.aspx"&gt;Cygon&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;For the past few days my girlfriend and I have started watching &lt;a href="http://anbat.toonzone.net/btas/page.html"&gt;Batman: The Animated Series&lt;/a&gt;. One of several excellent cartoon series released by Warner Brothers in the mid ninties. I'm still impressed with how they managed to create such a surprisingly mature cartoon that was still accessable to children.&lt;br /&gt;&lt;br /&gt;"But, what does this have to do with the game?" you might ask... One feature with Batman that stood out for me when I first watched it, and stands out even more now, are the amazing Art Deco images that pervade the entire series. I love the dichotomy of the style. With the right execution it can look both elegant and inviting in one moment then evil and terrifying the next. It looks both futuristic and anachronistic at the same time. Art Deco is an incredibly rich artistic style which I'd love to explore within the game. The future of the past if you will.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_JrkDUcuKsWU/SsausX1uiXI/AAAAAAAAAAM/nGTKV8K7YVI/s1600-h/art+deco+train.jpg"&gt;&lt;img style="WIDTH: 320px; HEIGHT: 308px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5388186081532217714" border="0" alt="" src="http://4.bp.blogspot.com/_JrkDUcuKsWU/SsausX1uiXI/AAAAAAAAAAM/nGTKV8K7YVI/s320/art+deco+train.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;Just imagine something like this locomotive as a huge space-faring battleship... yeaaahhh :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-9052686149008896770?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/9052686149008896770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/perhaps-we-have-muse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/9052686149008896770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/9052686149008896770'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/10/perhaps-we-have-muse.html' title='Perhaps we have a muse'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_JrkDUcuKsWU/SsausX1uiXI/AAAAAAAAAAM/nGTKV8K7YVI/s72-c/art+deco+train.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-7878614269170752665</id><published>2009-09-27T11:05:00.001-07:00</published><updated>2009-09-27T12:00:08.543-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='me'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>About the Project...</title><content type='html'>I've always developed games as a hobby since I was a kid. I started with text-based games in QBASIC when I was about 7. Since then I've made shooters, puzzle games, tools and other stuff for my own amusement and the amusement of my friends in school. When I found out we had to do a large software project over eight months in our last year of school I immediately wanted to do a game.&lt;br /&gt;&lt;br /&gt;The project, currently untitled, is a space combat simulator game in the same vein as the Freespace series and X-Wing series of games. The game is planned to be set up something like Quake 3 with one player hosting a game session and other players joining. Game types would be free for all (deathmatch, keep-away etc.) and team-vs-team (capital ship assault, etc.)&lt;br /&gt;&lt;br /&gt;At this point I've finished enough of the initial planning and school-related junk that I can actually start development. I'm using XNA Game Studio 3.1 foras a development framework for the project. This provides a nice multi-platform base to work from and a good collection of documentation and sample code to boot. I'm mulling over using an existing graphics engine or rolling my own at the moment.&lt;br /&gt;&lt;br /&gt;There seems to be a decent selection of graphics engines aimed at the XNA environment out there however most of the ones I've looked at are specifically aimed at rendering terrains which isn't particularly helpful. I've narrowed my list down to TXNA and Nuclex. My choice now comes down to how easily I can exploit the engine for my vile purposes and, if I can't whether it'd be easier to tear the engine apart or code what I need as I need it.&lt;br /&gt;&lt;br /&gt;I'll be making my decision later this week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-7878614269170752665?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/7878614269170752665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/09/about-project.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7878614269170752665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/7878614269170752665'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/09/about-project.html' title='About the Project...'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3363665146978183397.post-2383178850557039650</id><published>2009-09-27T10:50:00.000-07:00</published><updated>2009-09-27T11:05:04.926-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='me'/><title type='text'>About Me...</title><content type='html'>Hi, I'm a college student currently in the final year of my program at Conestoga College. One of the tasks we have to complete in order to graduate the program is to complete a software systems project over the next two semesters. For my project I chose to develop a multi-player action game on the XNA platform.&lt;br /&gt;&lt;br /&gt;This blog will be about the various challenges that I encounter during the development of my game project. This includes coding issues, sceenshots, school-related crap and anything else I feel like blogging about. I intend to make a post on this blog at least once a week.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Besides this blog I'm also an occasional poster on the XNA community under the name "Dan Dan Dan Dan"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3363665146978183397-2383178850557039650?l=dandandandandev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dandandandandev.blogspot.com/feeds/2383178850557039650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dandandandandev.blogspot.com/2009/09/about-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2383178850557039650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3363665146978183397/posts/default/2383178850557039650'/><link rel='alternate' type='text/html' href='http://dandandandandev.blogspot.com/2009/09/about-me.html' title='About Me...'/><author><name>Dan Dan Dan Dan</name><uri>http://www.blogger.com/profile/13901112964785358346</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_JrkDUcuKsWU/SvjdmMFHozI/AAAAAAAAAAY/p4b27o-vlO0/S220/Kill_it_with_fire.gif'/></author><thr:total>0</thr:total></entry></feed>
