Tater Salad

You can chop em up, mash em up, or boil em in a stew.

Silverlight Game Development Post Mortem

Posted by caseyrayl on June 28, 2007

Well the game that I alluded to in some of my previous posts is now live. I am biased of course, but I am pleased with how it turned out. I think it is pretty fun to play and that is really the most important thing.

 

Anyway, there is quite a bit of discussion around the Flash/Flex and Silverlight development communities about which platform is better and why. While most of these conversations have been primarily speculative I think that after going through an actual development cycle with Silverlight I have something to contribute to the conversation. The Adobe camp radicals would have you believe that Silverlight will never amount to a hill of beans, and the Microsoft camp radicals would have you believe that Silverlight is going to put Flash six feet under. In my opinion they are both wrong. Right now a meaningful comparison between the two products is very difficult because of the state of Silverlight. It just is not fair to compare a full release product suite with one that is in various stages of development. In spite of that I am going to talk about some of the things that Zero Gravity utilized successfully in Silverlight and the processes we went through to build the game along with some of the things that are lacking and caused me some frustration, discuss some design considerations, and then wrap up with what I think the current state of Silverlight is.

 

As I mentioned in my previous post, we had quite a bit of concern initially that the size of xaml files would make web delivery of a moderate to large scale Silverlight application prohibitive. However the ability to archive assets and extract them at runtime provided a solution which the game utilizes in the form of a preloader. Virtually every asset, with the exception of some very small xaml files embedded in the assembly for the textbox control, are archived and pulled during the preload process of game initialization. Also, all of the video (wmv), audio (mp3), and images (png and jpg) in the game are built from dynamic MediaElement and Image construction. Their sources are set directly from the archived asset. I expect that asset archiving of this nature will quickly become a standard practice in Silverlight development unless Microsoft jumps the gun and gives us utilities to abstract the process entirely.

 

Included in our asset archive are all of our xml files that specify the metadata about each game board and the definition of the boards themselves. Unfortunately right now the only utilities that Silverlight provides to manipulate xml are the XmlReader and XmlWriter classes. For those who are not familiar with the .NET framework, the XmlReader class is a low level xml string tokenizer that allows forward only analysis of an xml string. It is a cumbersome way of parsing xml and will hopefully become unnecessary due to the eventual introduction of LINQ to the Silverlight platform. You can learn about LINQ here. I have not seen a specific date on when it will be introduced, so if you plan on building a Silverlight application anytime soon, say hello to the XmlReader.

 

On a more positive note, network communication development in Silverlight went surprisingly well for us. Initially I stubbed out a class where I intended to write my client side code for the communication to the web service that I knew was going to be built with ASP.NET and dummied up the returns so that my UI development could continue. Now normally in a Flash world, at some point myself and the service engineer would sit down and agree upon our data exchange format and API, then go off and write our respective pieces, and then come back and integrate them. But in Silverlight, we were both working in Orcas under the same project solution, and the service engineer was able to build his project right there and write both sides of the communication interface, one in his web service, and the other in my stubbed out class within the game. At that point all I had to do was refactor a bit of code to make sure my method calls matched his slightly modified API (due to emerging specs of course) and we were done. We were both pleased with how it progressed and the efficiency we gained from building the game with that paradigm.

 

Alright so enough of the infrastructure stuff and on to some view coding. Unfortunately when I started this project I had only an understanding of the C# language, but lacked any understanding of conventional visual windows programming. Perhaps if I had that understanding the concept of custom controls would have immediately clicked for me, but I didn’t discover their power until several weeks in. At this point I would equate them to Flash components because they serve the same sort of role but with an added facility which became the solution for a real stumbling block for me in Silverlight. In xaml markup, you can name your visual elements using the x:Name property and then use that name to locate the element in your managed code. The catch is that the names must be unique, regardless of where they fall in the structure of the xaml. Giving two elements the same name in a xaml file will cause an exception when the xaml is read, regardless of how you try to read it. Another even more problematic issue with this is that even if you have unique names in a xaml asset, you can only ever have one of those registered in the display list, because if you create another and attempt to add it, a name collision is occurring somewhere in the tree. The solution to this is the custom control. Each control creates a namescope which prevents name collisions between multiple instances of the same asset. Once I discovered this, I refactored all of the games board elements such as the player, the ship, the blocks, tubes, teleporters, and switches over to controls. The controls then encapsulate all the logic necessary to manipulate the asset, including its xaml defined animations, and expose functions necessary for clients to use them. I also used controls to expose properties in a simpler and more familiar way. A couple of examples of this are Canvas.LeftProperty masked as an “x” setter, a xaml defined ScaleTransform masked as a “scale” setter, and a xaml defined RotateTransform masked as a “rotation” setter. In general I do not think that the power of controls is adequately explained in the Silverlight tutorials, but then again, the documentation is currently quite sparse, so the power of a lot of things is not adequately explained.

 

The other view element that I want to discuss is controls and containers. Basically Silverlight lacks some very fundamental controls right now, most notably a text input facility, and does not support containers at all. Their absence means a huge loss of productivity for anyone currently trying to build a Silverlight application. Zero Gravity uses custom code to achieve its liquid layout and uses a freely available controls/containers library published by Dave Relyea which you can get here to implement its text input fields. Daves’ controls were quite helpful to me but they cannot take the place of actual Silverlight framework support for these facilities (Dave never claimed they could). The upside to this situation is that I have been told in no uncertain terms that a control and container library will be added to Silverlight but I do not expect it by the release of 1.0.

 

The promises of controls and containers are not the only promises Microsoft is laying down right now. Data binding and skinning support are also slated for the framework. When they get included is something I cannot answer, but the fact that these discussions are taking place, combined with the current state of the 1.1 alpha leads me to believe that Silverlight has a very bright future in the development community. However, that community is only half of what makes successful RIAs. We can’t forget about the design community and I do not think they are nearly as excited about the power of the Expression Suite and Silverlight.

 

Expression Blend is the primary animation facility for xaml assets and from my perspective it is so far out of sync with Silverlight right now that an efficient workflow between developer and designer isn’t achievable. Basically Blend is entirely geared toward WPF right now and the xaml it produces isn’t going to function in Silverlight without rework that a designer isn’t likely to do. The end result was that I had to edit quite a large amount of xaml by hand to get the assets to work. I don’t blame my designers for this at all. Sure you can see the xaml that Blend is building in the program at any time, but should a designer really need to understand that Silverlight does not support the Viewbox yet and that Canvas has to be used for everything? No, that would be ridiculous. This particular stumbling block is very much on Microsofts radar and I know they intend for the integration between the applications in the Expression Suite and Silverlight to be very tight. I am not worried about them fixing it in the future.

 

However, there are other design related problems that unfortunately I cannot speak to first hand, but can give at least an impression of. Blend is reportedly a fairly weak alternative to Flash when it comes to animation. Apparently the tools are rudimentary and the control required to animate efficiently is absent. I think that if anything is going to slow down Silverlight, this is it. Microsoft cannot sway a large number of designers the way the can sway a large number of developers because the pool of developers ready to learn Silverlight is so vast, while the pool of designers ready to leave Adobe is so small. Only time will tell with this and I wish I could give more insight into the situation, but I cannot animate my way out of a wet paper bag in Flash or Blend so I will say no more.

 

Looking back over this post you might have caught on that there are a lot of things left “to the future” with Silverlight, which goes back to my original point that making comparisons with Flash right now is just premature. The potential of Silverlight is obvious and very real, but I would caution anyone looking at it as a solution today. Right now Adobe has a superior technical and design platform, and that isn’t going to change over night. I believe Microsoft is going to close the technical gap quickly, and how fast they can close the design gap remains to be seen. Overall I would encourage any RIA developer out there to investigate what Silverlight has to offer because it might not be long before it becomes a very marketable skill.

 

-Casey

Posted in Uncategorized | 5 Comments »

Compressed Assets in Silverlight.

Posted by caseyrayl on June 8, 2007

You might have noticed that XAML files can get massive, much larger than a corresponding SWF file to represent the given vector art and animations.  The solution to this that I found was posted over at Tim Huers blog.  The code Tim posted is for JavaScript, but I found that the process works equally well in managed C#.  Basically you can wrap all of your assets up into a zip archive, pull the archive down from the server at runtime, extract what you need from it and display it dynamically.

The process worked well with one caveat.  Certain png files that existed in my application would not load at runtime from code.  You could link them in the xaml and they worked properly, but when loaded at runtime threw a COM exception.  I tested plain old xml, xaml, jpg, and wmv files without a problem.  Even 25% of my png files worked properly.  Some had transparency, some didn’t, and I was not able to discern a pattern.

In spite of the png compatibility issue, I think zip archives are definitely the way to go when pulling down remote assets.  Visual Studio gives you the ability to embed any asset you want directly into the assembly, but it does not compress them.  What would be ideal is if the assets embedded into the dll were compressed internally and the archiving was totally abstracted from the application programmer, but until Microsoft decides they want to do that, using a zip archive to house assets is the next best thing.

-Casey

Posted in Uncategorized | Leave a Comment »

Dynamically Resizing a Silverlight Control from Managed Code

Posted by caseyrayl on May 23, 2007

I discovered recently that the root silverlight control is not available from managed code in the 1.1 alpha.  Microsoft intends to make it available and it will probably be there in the beta, but for those of us trying to manipulate our RIAs with information from the control before the beta hits, another solution is in order.

 

The way I solved this was by using JavaScript to call into my managed code.  The basic setup involved specifying [Scriptable] elements in the managed code, specifically the class that interprets the calls (for me this was my main handling class linked from the XAML) and any getters/setters and functions within that class you want to expose to JavaScript.  I exposed a width and height setter, a function to handle a resize event from the browser, as well as a “main” function to get the app running.  The last requirement is a registration of the variable name from which you can access the class from JavaScript.  To do this you use the WebApplication.Current.RegisterScriptableObject() static function call.  Incredibly intuitive!

 

Then in the JavaScript file, I registered an event to handle the post load of the Silverlight control.   Within that function I extract the width and height from the control and set them into the managed code.  Then I register an event on the control to receive resize events.  Finally I tell the managed application to begin execution.

 

When the browser is resized, my JavaScript handler cascades the information down into the managed code and the entire app resizes to fit into the browser properly.  Sort of the long way to go about doing something that should be fairly straightforward, but it works for now.

 

-Casey

Posted in Uncategorized | Leave a Comment »

Styled selected item in a ComboBox

Posted by caseyrayl on May 9, 2007

For some reason Flex 2 does not automatically draw the icon of the selected item in a ComboBox. I found some discussion about how to implement this, and came up with a slightly different solution that I thought I would throw out there.

You want to start off with a ComboBox extension that has two private properties: a DisplayObject to reference the icon, and a Shape to house the icons mask. Override createChildren and add the mask as a child. Override measure and check for your icon, if it exists add its width to your measuredWidth. Finally, override updateDisplayList and do a check on the selectedItem property. If it has a valid icon property, instantiate it as you would a class and cast it to a DisplayObject, then assign it to you private icon reference. Draw a rectangle in you mask Shape using the unscaledWidth of the component minus the value of the arrowButtonWidth style as the width of the mask. Then move your text over to the right of the icon.

You should add some more code to ensure the mask gets cleared and that you reposition the text if you move to a selectedItem with no icon attached after viewing one that did have one, but other than that you are good to go.

-Casey

Posted in Uncategorized | Leave a Comment »

Runtime CSS Loading

Posted by caseyrayl on April 25, 2007

This topic has been discussed quite a bit elsewhere so it is difficult to add much to the conversation, but I did experience a few issues that I haven’t seen described yet and some that bear repeating. 

The basic idea here is that we want to compile a CSS file into a swf and load it at runtime.  I used a configuration XML file to specify the actual style setting for my app rather than put an mx:Style node in my mxml anywhere, or hardcode the path to the style swf. 

Both Flex Builder 2 and the Eclipse plug-in for FB2 have the ability to compile CSS files for you.  I work in the Eclipse plug-in for FB2, so all of my experience is from that environment.  Supposedly, all you have to do is right click on them in the Explorer/Navigator window of the IDE and select “Compile to SWF”.  However I had multiple issues with this and found very few resources that describe the dependencies of the CSS compilation.  Through trial and error, this is what I have discovered. 

The CSS file must be at the root of the project.  If it is not, compilation will fail with mxmlc telling you that the source file is not correctly packaged.  If you try to package it in a similar fashion to an AS source file, you will receive a syntax violation. 

Also, if your CSS file uses any skins that utilize the ClassReference facility those classes and their entire class hierarchy must exist solely within your project.  If you utilize classes that exist in externally linked directories or classes that extend other classes in externally linked directories, compilation will fail with the type declarations of these externally linked classes being unrecognized.  The only workaround I found for this was specifying the source-path and library-path command line parameters for mxmlc myself and compiling manually.  Luckily I had access to an ANT script that was updated fairly easily to support this, but it is still annoying not to be able to compile certain skins directly within Flex Builder 2. 

If anyone knows how to circumvent these issues I would be all ears.  Otherwise, I hope this saves you some time from banging your head into your keyboard. 

-Casey

Posted in Uncategorized | 2 Comments »

More Than Meets the Eye

Posted by caseyrayl on April 11, 2007

I decided to continue my image theme from my last post. This time though I am going to talk about some interesting transformations I just did to some BitmapData objects. The most esoteric (for me) color transformations involved moving from RGB color to black & white (also called desaturation) or sepia. I accomplished this via the applyFilter function of the BitmapData object and passed it unique ColorMatrixFilters. The exact values within the matrices are the real trick here. Behold!

Black and White ColorMatrixFilter matrix:

(r_lum, g_lum, b_lum, 0, 0,

r_lum, g_lum, b_lum, 0, 0,

r_lum, g_lum, b_lum, 0, 0,

0 , 0 , 0 , 1, 0)

Where

r_lum = 0.212671;

g_lum = 0.715160;

b_lum = 0.072169;

OR

r_lum = 0.3086;

g_lum = 0.6094;

b_lum = 0.0820;

The selection of the “luminance vector” value will likely depend on your renderer, but it seems Flash likes the first more.

And the sepia ColorMatrixFilter matrix:

(0.393 , 0.749 , 0.189 , 0.0 , 0.0 ,

0.349 , 0.686 , 0.168 , 0.0 , 0.0 ,

0.272 , 0.534 , 0.131 , 0.0 , 0.0 ,

0.0 , 0.0 , 0.0 , 1.0 , 1.0)

If you are interested in a very dynamic color transformation utility, a class in AS2 that implements some cool functionality (in a very AS3 convertible form) is the ColorMatrix class by Quasimondo.

Posted in Uncategorized | Leave a Comment »

Implement sloppy borders cleanly.

Posted by caseyrayl on April 6, 2007

I was recently tasked with drawing sloppy borders over a dynamically sized image which was draggable within its parent container and masked by that container.  The border could only be drawn around the visible portion of the image.  It took me awhile to grasp the math involved, so I figured I would share it for anyone else who might need to do the same thing. 

There were two pieces of metadata used in the calculations though you could get by with just one when using symmetric sloppy borders.  The top left point and the bottom right point within the border “window” are needed to understand how much visible space the image must take up. 

First, derive the viewable width and height of the image within the container, as well as its position.  You will need these values to scale and locate the border. 

Next find the ratio of the size of the entire border file to the size of the “window” in the sloppy border using the metadata you have for the particular file.  This ratio should be larger than 1 for each axis.  Set your loaded borders width and height to the size of the image multiplied by this ratio. 

Now find the ratio of the position (each axis respectively) of the top left metadata point to the total size of the border file.  Multiply these ratios by the width and height of the border you calculated previously, and subtract this value from the location of the image.  Presto!  You have a dynamically sized and positioned sloppy border on your image.  Damn it feels good to be a gangster. 

-Casey

 

Posted in Uncategorized | Leave a Comment »

FlexBook Conquers the World.

Posted by caseyrayl on March 28, 2007

So I began learning AS3 and Flex2 recently in order to support a native Flex2 RIA. My first task was to integrate Ely Greenfields new FlexBook component into several areas of the application. The work is probably 80% done now and I thought I would share a few interesting things about my odyssey into the component. FlexBook uses an ICollectionView as its content and specific elements for the front and back cover. These elements need to be UIComponent instances. However, the code in the FlexBook used to set the content collection expected it as either a primitive array type or an XMLList. I had to pass in a native ICollectionView, so an update to the component was required. Also, Ely distributed several interesting examples along with the component source, and I noticed that in several of them there were utility methods specified to flip the pages of the book forward or backward. I wanted to use these but did not want to rewrite them each time, so I took the logic and inserted it directly into the FlexBook class. Along the way I had to update the “turn to previous page” method because it would not move to the cover, if one existed. Other than that, the FlexBook worked quite well. I did notice some odd logic in its updateContent function, but Ely has said this is rough code, so that type of thing can be expected.

I have also started experimenting with WPF/E for an upcoming project using the technology. I have never used JavaScript before so I have to learn it along with the WPF/E framework. So far it has been a mixed bag for me. Syntactically and semantically JavaScript feels like a step backwards from working in languages like Java and ActionScript 3. On the other hand the WPF/E framework is interesting. The drawing API is fairly robust and the animation system is straightforward. I have not yet seen what it is truly capable of. Some tech specific things that I have encountered that I thought were odd are that the WPF/E Image object cannot have its source set more than once without throwing a JavaScript error. Also, the new Blend application for generating vector art assets in XAML only supports scripting in C# for WPF applications, which is a bummer.

Hopefully I will have a meatier post about WPF/E next time.

Posted in Uncategorized | 1 Comment »