Wednesday, October 31, 2007

Why try if you can't be the best?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_try_if_you_cant_be_the_best.htm]

In a competitive world of information overload, with millions of other developers, there will always be someone better than you. Even if you pick a niche, chances are there will still be someone even more talented than you in that niche. "There's always a bigger fish in the sea". Furthermore, learning any new field always requires hard work and making mistakes. So, a common question is "Why should I try if I can't be the best?" For example, why learn how to build web applications, or computer games, or any programming, when there will always be someone so much better?

 

It's a good question, one that unfortunately intimidates a lot of people from trying in the first place. There are several reasons:

  • You don't need to be the best. You can still get a job, contribute to the field, and have fun.

  • You can learn something just for the enjoyment of learning it. For example, you may enjoy making a Silverlight or XNA game just to have fun - it doesn't have to be the next Super Mario or Age of Empires. Similarly, I go running just for my own enjoyment - even though I make a turtle look fast.

  • The act of trying will improve your character, and still teach you other skills.

  • Often the "best" isn't available (they're already locked up in another job or project), so one's moderate skills are still needed.

  • You can still add value, even if you're not the best. Often star developers want to coordinate other people to help build a project bigger than what any one person can create by themselves.

  • Even if you're not the best, you can still probably help other people more junior than yourself. I.e., you're probably still an expert to someone - even if it's just a young student, intern, or someone changing careers.

  • Everyone has to start someplace. You may even become that super-expert someday.

Someone who constantly passes up the opportunity to learn something new, simply because they can't be the expert at it, is selling themselves short. As a father pointed out in the movie Facing the Giants, in a scene about a soccer kid hesitant to try out for the football team because he may not make the cuts, "You aren't on the team right now. You can't be any less on the team than you are right now." Likewise in development, if you don't know a technology and you're hesitant to learn because you're not an expert, you can't be any less of an expert than you are right now. You might as well take a stab at something you enjoy, have fun along the way, and become good enough to do what you want to do. I'll never be Michael Jordan, but it's still fun to shoot a few hoops.

Tuesday, October 30, 2007

Silverlight: Unit Testing

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/silverlight_unit_testing.htm]

Silverlight 1.1 lets you use C# code, which is awesome. However, the next natural question for a developer is "How will I test that code?" For example, any silverlight game, like the TruckWars game that I've been blogging about, has lots of backend logic for collision detection, movement algorithms, interactions between units, checking for victory conditions, etc... Ideally, you could follow the standard pattern of having a core assembly with all the logic (a Silverlight class library), exposed with just a light GUI wrapper (a Silverlight project). Then you could add that class library to a test harness (like MSTest) and do Test-Driven-Development.

 

The problem is that Silverlight doesn't let you mix Silverlight and non-Silverlight assemblies. So, you can't add your SL class library to a test harness (like MSTest), nor can you even add an assembly to your Silverlight library (like NUnit). [If there's a way to do this, I haven't seen it yet, and I'm all ears].

 

So, there is a work-around. What you could do is create an MSTest project, and then place your Silverlight class library in a child folder of that MSTest project. Then each project has references to all the same physical files.

 

For example, have a Test solution at:

    FolderSilverlight\Tank\Tank.Test\Tank.Test.csproj

 

And then your silverlight class library, called "SilverlightUtilities", as a child:

    FolderSilverlight\Tank\Tank.Test\SilverlightUtilities\SilverlightUtilities.csproj

 

Then, say you have a silverlight file to test, like "MathHelper.cs", located in the SilverlightUtilities:

    FolderSilverlight\Tank\Tank.Test\SilverlightUtilities\MathHelper.cs

   

Both projects, "Tank.Test" and "SilverlightUtilities" can have references to the same physical file, "MathHelper.cs" (there is only one copy of this file, but it gets referenced by two projects). Essentially, this means that the Tank.Test Project includes both the source code, and the test code.

 

Note, you'll need to give the Test project references to several Silverlight prerequisites:

  • agclr - C:\Program Files\Microsoft Silverlight\agclr.dll

  • System.Core - C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll

  • System.Silverlight - C:\Program Files\Microsoft Silverlight\System.Silverlight.dll

  • System.Xml.Core - C:\Program Files\Microsoft Silverlight\System.Xml.Core.dll

This does mean that as you add each new C# file, you have to build two projects, but an automated script should make that easy.

 

Also, I still haven't found a way to test code that uses Xaml (like a Silverlight Control). I keep getting the error:

 

    Project file must include the .NET Framework assembly 'WindowsBase, PresentationCore, PresentationFramework' in the reference list.

 

I'm sure there's a way to deal with this, but I haven't found it yet.

 

I hope that because Silverlight is still a beta, that Microsoft will eventually make it easier to unit test. In the meantime, it's good to be able to continue writing tests, even on Silverlight.

 

Monday, October 29, 2007

Silverlight: Using isolated storage to save client data

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/silverlight_using_isolated_storage_to_save_client_data.htm]

Silverlight allows developers to persist data to a file on the client's machine using Isolated Storage. This is just like writing a normal file, except that it handles a bunch of extra grunt work to write that file to unique spot for the user and application. So, instead of writing a file to "C:\Temp\myStuff.txt", that all users and applications can see, it writes it to something essentially like "FolderRoot\UserName\Application\myStuff.txt" (although, the real directory structure is a little more optimized and less plain-text).

 

What's also interesting about Silverlight isolated storage is that unlike other browser client-side repositories, like a cookie, (A) it is shared across browsers, and (B) it's not cleared by deleting temp files.

 

For example, in my Silverlight arcade TruckWars game, it uses isolated storage to determine what's the highest level you've reached, effectively saving your progress. The code has a class, IsolatedStorageHelper, that provides static utility methods to SetData, GetData, and Delete a file:

 

using System.IO.IsolatedStorage; using System.IO;  namespace SilverlightUtilities {   public class IsolatedStorageHelper   {     ///      /// Writes the given data to the given fileName in isolated storage.     /// If the file already exists, it is overridden.     /// If the file does not exist, it is created.     ///      ///      ///      ///      public static void SetData(string strData, string strFileName)     {       using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())       {         using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(strFileName, FileMode.Create, isoStore))         {           using (StreamWriter writer = new StreamWriter(isoStream))           {             writer.Write(strData);           }         }       }     }      ///      /// Gets the data from the fiven file.     /// Returns null if the file does not exist.     ///      ///      ///      public static string GetData(string strFileName)     {       using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())       {         if (isoStore.CurrentSize == 0)           return null;          using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(strFileName, FileMode.Open, isoStore))         {           using (StreamReader reader = new StreamReader(isoStream))           {             // Read the first line from the file.             string s = reader.ReadLine();             return s;           }         }       }     }      public static void DeleteFile(string strFileName)     {       using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())       {         if (isoStore.CurrentSize == 0)           return;          isoStore.DeleteFile(strFileName);       }     }   } }

Sunday, October 28, 2007

Releases Silverlight TruckWars v1.1

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/releases_silverlight_truckwars_v11.htm]

Silverlight TruckWars is a real-time strategy game built entirely in Silverlight. I recently releases version 1.1, which as some new features:

  • More creatures:

    • Ambulance that heals

    • Growing forests

    • Moving bricks

    • SignPost to display helpful messages

  • New levels, including tutorials and new graphics

  • Better game management - saves your progress, and an HTML toolbar that lets you jump to previously solved levels, restart the game

  • A help page

These really help round out the game.

You canplay the game online here. Being Silverlight, it essentially runs within a blog post, so feel free to leave comments on that (or any) post.

 

I'll blog more about these in the future. Definitely there are more enhancements I'd like to make. I'd group these into improving the engine, and adding new creatures to better demonstrate that engine. In particular, new features I'd like:

  • Incorporate Farseer Physics Engine for better collision detection

  • Add a game-difficult setting

  • Improve movement algorithms - i.e. a unit should be smart enough to move around a concave polygon.

  • Add a "building" type object that can create new units.

  • Something with railroad tracks - for my son :)
     



Monday, October 22, 2007

Paylocity is hiring for a .Net/C# Programmer (in Chicago)

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/paylocity_is_hiring_for_a_netc_programmer_in_chicago.htm]

Paylocity, a Chicago-based payroll company, is hiring for a .Net / C# Programmer. We have a good team culture, a growing company, and are consistently voted one of the best places to work for. The position is in Internal Development, and takes a hybrid of business and technology skills. This would be an excellent opportunity for a junior or mid-career programmer, as it provides tons of learning potential.

While it isn't my direct department (I'm in software engineering), I constantly hear good things about them.

 

If you're interested, feel free to either apply online, or contact me directly (just include your contact info if you do so that I can reply).

Sunday, October 21, 2007

Silverlight: Read xml file in FireFox (solve "Data at the root level is invalid")

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/silverlight_read_xml_file_in_firefox_solve_data_at_the_ro.htm]

Any app eventually needs to read data; and it's very likely that for Silverlight, that data will be XML files on your web server. For example, in the real-time strategy TruckWars game, each level is stored as an XML file (named 1.xml, 2.xml, etc...). The Silverlightquickstart tutorials describe how to load an Xml file into an XmlReader (there is no XmLDocument for silverlight yet). While this works great in IE, it actually has a problem in FireFox. FF tries to read the xml file, but it starts with three extra bits used for reading the encoding type. These three extra bits screw up the XmlReader, and you get the error:

 

"Data at the root level is invalid. Line 1, position 1."

 

This has something to do with theunicode.GetPreamble().

 

Practically, there's probably some way to overload the reader class, or set something on the Xml file. But I couldn't figure that out. I tried several things:

  1. Use reader.ReadToFollowing("myNode"); But those first few bytes prevent me from reading anything.

  2. I tried removing , but no luck

  3. Based on anMSDN forum, I tried removing this first line:

  4. In the StreamReader class, I set the detectEncodingFromByteOrderMarks constructor property (trying both true and false), but no luck.

  5. I tried modifying the Xml Reader to directly get from URI. However, I got the error: "Support for http:// URIs is not yet implemented."

  6. I tried overloading the XmlReader with XmlReaderSettings (and setting IgnoreProcessingInstructions )

  7. I tried reading the first three bytes of stream to "skim off" the problem characters, but it still had the same problem

So, none of those attempts worked. Eventually, I got a work-around. I would read the entire xml file into a string, and then skip the first problem characters until I go to the "

    public static XmlReader CreateXmlReader(string strRelativePath)    {      HttpWebResponse response = null;      StreamReader sr = null;      try      {        //first create standard stream:        Uri u = new Uri(strRelativePath, UriKind.Relative);        HttpWebRequest request = new BrowserHttpWebRequest(u);        response = request.GetResponse();        Stream content = response.GetResponseStream();        sr = new StreamReader(content);        string s2 = sr.ReadToEnd();        //Skim off unicode.GetPreamble()        //In firefox, this would be first three bytes for UTF8        int intIndex = s2.IndexOf(");        s2 = s2.Substring(intIndex);        StringReader sr2 = new StringReader(s2);        return XmlReader.Create(sr2);      }      catch (Exception ex)      {        throw;  //Wrap in try catch for now. Will add better error-handling later.      }    }

This solved my problem, worked in both FireFox and IE, an performed well enough for my needs.

Wednesday, October 17, 2007

Silverlight - Truck Wars Strategy Game v2.0

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/silverlight__truck_wars_strategy_game.htm]

Release 2.0 - Migrated to SL2

Microsoft has officially released Silverlight 2.0, and there are more breaking changes. I haven't updated TruckWars yet (it's gone through Alpha 1.1, Beta 1, Beta 2... running out of gas). Here's a screen shot of what it looked like. I hope to migrate sometime in the future, perhaps even adding dynamic scripting for the objects.

 

truckwars_screenshot_1_2.jpeg


Release 2.0 - Migrated to SL2 Beta 2

I started working on TruckWars as a way to learn Silverlight back in the Alpha last year. There have since been two more betas (with plenty ofbreaking changes), but I've finally migrated it.

 

Things of note - Beta 1 started supporting buttons, which obviously simplified things. For example, it helped me remove keyboard input. It also had some subtle changes that affected the gameplay. Also, there still is no dropdown. Before I was using an HTML dropdown to select the levels. Rather than jump through hoops, I just ceded the dropdown part until the next release.

 

Because the code has been migrated from an alpha, to a beta, to another beta, it's becoming pretty screwy. Not the best, most agile code out there, but good for a demo of what cool stuff Silverlight can do.


NOTE: You need to view this page in a browser in order to see the game; it doesn't show up in most RSS feeders.

 

Release 1.3: Now Open-Sourced

TruckWars is a simple SilverLight real-time-strategy game. You control the green units. You select a unit by left-clicking it. You move a unit by drag and drop. You attack an enemy unit by moving your unit into the enemy unit's space. The goal is to push all the green buttons down.TruckWars is now open-sourced at CodePlex. It's also on the Silverlight Gallery.

Release 1.1

This is a simple SilverLight real-time-strategy game. You control the green units. You select a unit by left-clicking it. You move a unit by drag and drop. You attack an enemy unit by moving your unit into the enemy unit's space. The goal is to push the numbered crates onto the pink "Victory" tiles, and then hit the green semi-circle button. You can see more info on the release notes.

Release 1.0

I converted the XNA game to Silverlight. This is a simple SilverLight real-time-strategy game. You control the green units. You select a unit by left-clicking it. You move a unit by drag and drop. You attack an enemy unit by moving your unit into the enemy unit's space. (SilverLight only allows a left click). Currently only the tanks can attack. The ambulance and pickup truck don't do anything yet. The goal is to push the numbered crates onto the pink "Victory" tiles, and then hit the green semi-circle button. Select the game (to activate it), and then click "spacebar" to start. Obviously this is just a simple test of SilverLight, and I'm open to suggestions. I'm going to explain the code in the next several posts. I was inspired by my son's love of trucks to use the truck theme. I was definitely helped by Bill Reiss's good Silverlight Tutorials.

Tuesday, October 16, 2007

XNA Real-Time-Strategy Game (with source code)

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/xna_realtimestrategy_game_with_source_code.htm]

I mentioned in my last post about XNA that I've created a sample game, complete with full source code.

 

 

You control the green tank by using the mouse. Left moves, right fires. The goal is to push the numbered crates onto the pink "Victory" tiles, and then hit the green semi-circle button. This demonstrates several things:

  • Collisions - this uses a simply polygon collision detection. It also handles heights - a fireball hovers, so it can pass over the water, but the tanks cannot.

  • User input - collecting mouse input (position, left, right buttons)

  • Animation - the water animates

  • Multiple creatures of different sizes. The green bushes (the square things) increase in size as your tank gets closer.

  • Interacting objects - you can push crates, fire at other units, hit the push button, and collect a powerup to increase your firing rate.

  • Messages

  • Opacity

  • A dashboard section on the button for user information

  • The ability to pause the game - which freezes everything (including the game clock).

Note that all the graphics were made with MSPaint.

 

The code is pretty sloppy, as it was just a toy project and my main point was to explore XNA. There's a ton that could be improved about it.

 

Obviously it's just a cute sample. Especially as XNA can handle scrolling, 3D games, and a lot more, this only skims the surface.

 

One point of note is unit-testing. There is a lot of complex code (movement algorithms, models, collisions, interactions, etc...) that should ideally be tested. However Visual C# express doesn't support unit-testing. So, I made the core DLL be referenced in another solution, which can then test it.

 

Next up: re-writing this in Silverlight. I'll go into more of the details there.

Monday, October 15, 2007

XNA Game Development

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/xna_game_development.htm]

XNA is a Microsoft platform for easily creating games. These can run on Windows, and even the XBox.

 

Essentially, XNA handles the difficult part of image rendering, and provides the developer a simple API. Bill Reiss provides some excellent tutorials to get you started.

 

An XNA project has the Game class, which provides three main methods;

  1. Initialize - sets everything up

  2. Update - updates the models based on a game clock

  3. Draw - renders images to the screen based on the game clock, and what you updated.

This is a very intuitive API which makes it easy to make simple games, especially 2D classics.

 

What I find interesting about XNA is that many developers got their start by trying to program simple computer games. However, back in the 80s or 90s, the bar was high because it's relatively difficult to do the image rendering, especially something fast enough for a real game. Many more developers can do the algorithms and simple logic than can do the rendering. Even with Windows GDI+, it just wasn't fast enough. But XNA actually works fast enough to make it worth while.

 

XNA games can also bedeployed to other Windows machines, you "just" need to install: (1) .net 2.0 redistributable, (2) XNA redistributable, (3) Direct X. It's motivating to be able to share your work with others.

 

In the next upcoming posts, I'll provide an XNA sample game I created, and compare it to Silverlight.

Wednesday, October 3, 2007

Five hours for one line of code

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/five_hours_for_one_line_of_code.htm]

The other day I spent five hours to write a single line of code. This has happened before, and it always makes me think "why?" To the non-developer it could sound crazy, I've heard many say things like: "it was just one line; you should be writing 100 line of code per hour to justify our budget."

 

The issues involved are:

  1. The developer is working on a legacy sub-system that they had never seen before (perhaps the original creators are no longer available, and you need to dig through their work)

  2. That sub-system is written in a different language

  3. The sub-system itself was complicated

  4. The line to be added was an undocumented feature

  5. It took very long to test each change

  6. This was a mission-critical feature, so it needed to work perfectly

You add those all together, and it's easy to see it the other way - "Wow, I'm glad we got that handled in only half a day".

 

Also, this is a rare case. A developer can write many lines of new code per day.

 

I think it touches on a bigger issue - just because the end result is simple doesn't mean that finding that result is simple too. For example, the total population for the US at a given moment is a specific number (somewhere around 300 million, off the top of my head). However, to find that exact number requires a huge bureaucracy and coordination among many civil organizations (like hospitals and immigration offices).

 

It something that any developer could come across, and should therefore be prepared to explain to their managers if needed.