Pages

Monday, July 20, 2009

Loading SVG from a Silverlight Application

The problem:
I want to use SVG files as the underlying graphics format for my Silverlight game.

Why?

First why do I want to use vector graphics for all my game graphics assets? Since vector graphics are resolution independent this allows me to create the content once and scale it to the required resolution depending on the target platform without any loss of quality(which is not the case with bitmap image formats like PNG). The same graphic asset can then be used today on the web, tomorrow on some lower resoluton mobile device and later on a full screen view on a HDTV.

What is SVG? In short, SVG is an open file format that describes a vector graphics image. There are free and excellent tools like Inkscape that lets us create images in the SVG format.

What is XAML? XAML is the basic application markup language for Silverlight and is also very good at describing vector graphics. Then why don't I just use XAML for my vector graphics? The main reason is that I want to keep the original format of my game assets to be portable to other platforms.

So thats the problem in short - I want to be able to create my game graphics in Inkscape as SVG and load it into my Silverlight Application.

The solutions that didn't work
The solution path is obvious - Convert SVG to XAML which Silverlight understands and load it into the Silverlight application. Either I can do the conversion during build time or do it dynamically at runtime. The solution which can load at runtime would get extra bonus points.

So I looked at various existing conversion tools for converting from SVG to XAML.

Here is a list of the ones that I tried and rejected.

1) Inkscape XAML exporter - The current version on Windows has known bug and crashes. Also it is difficult to integrate this with the build process.
2) The commercial ViwerSVG - Allows to dynamically load SVG into a WPF application(Silverlight also I would assume). I gave it a quick spin and not very happy with the conversions. And the price tag was too heavy.
3) Next I tried the excellent XamlTune. The conversions from SVG to XAML were great and it had a command line utility which I could use as part of the build process. I saw the live version of XamlTune and was even more excited. The only problem was that the output from XamlTune works with WPF but is not exactly friendly towards the subset of XAML supported by Silverlight. I needed to find a better solution.

THE REAL SOLUTION : SVG2XAML.XSL
Enter svg2xaml.xsl. This is a XSL transform written originally by one Toine de Greef. It basically provides the rules to convert a SVG file to a XAML file and it supports Silverlight XAML! As it turns out Inkscape uses this same XSL to actually do the XAML export So I got the XSL from Inkscape since I thought it would have some extra bug fixes to it.

So now I could use a command line XSL processor like msxsl.exe and use SVG2XAML.xsl to convert SVG to XAML and it worked really well with the sample set of SVG files I had.

Now only the bonus question remained. Can I use svg2xaml.xsl to dynamically load SVG into my silverlight application? I had seen the live version of XamlTune. It seems to be using server processing for converting SVG to XAML. But that seems to be a waste of server resources. If I wrote a silverlight game I would like to avoid using sever resources since it costs money for the server CPU and bandwidth.

Can I do it entirely on the client side? As it turned out I can! Eventhough Silverlight itself doesn't support doing XSL Transforms it can call into javascript code which can do the XSL transform and return back the transformed XML.

Using client-side Javascript to convert SVG to XAML
The following is the Javascript code I used to do the XSL transforms from SVG to XAML. The script loads svg2xaml.xsl which in turn refers to colors.xml. I made some extra fixes to svg2xaml which allowed me to succesfully convert few more SVG files succesfully - You can get the updated svg2xaml.xsl and colors.xml.

You can use the following Javascript code in the page that loads the silverlight control.

function loadXMLDoc(xml, isFileName) {

var xmlDoc = null;

// code for IE
if (window.ActiveXObject) {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;

if (isFileName) {
xmlDoc.load(xml);
}
else {
xmlDoc.loadXML(xml);
}
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument) {

if (isFileName) {
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(xml);
}
else {
parser = new DOMParser();
xmlDoc = parser.parseFromString(xml, "text/xml");
}
}
else {
return null;
}

return (xmlDoc);
}

function svg2xaml(svgString) {
var xml = loadXMLDoc(svgString, false);
var xsl = loadXMLDoc("svg2xaml.xsl", true);

if ((xml != null) && (xsl != null)) {

// code for IE
if (window.ActiveXObject) {
result = xml.transformNode(xsl);
return result;
}
// code for Mozilla, Firefox, Opera, etc.
else {
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToDocument(xml)

var serializer = new XMLSerializer();
var xaml = serializer.serializeToString(resultDocument.documentElement);

return xaml;
}

}
else {
return null;
}
}


Then you can call this javascript function from your silverlight code to convert the SVG file to XAML which can then be loaded in the silverlight application. The following code prompts the user to select a SVG file on the local computer's file system and converts into XAML by calling into the javascript code using HtmlPage.Window.Invoke. It then displays it so that it fits the current silverlight control dimensions. "mapCanvas" in the code below is the just the main Canvas object that displays the loaded SVG image.

...
using System.IO;
using System.Windows.Browser;
using System.Xml;
using System.Windows.Markup;
...


OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = "Graphics files (*.svg)|*.svg";

if (fileDialog.ShowDialog() == true)
{
string svg = null;
using (StreamReader reader = fileDialog.File.OpenText())
{
// Store file content in 'text' variable
svg = reader.ReadToEnd();
}

try
{
// Call the Javascript XSLT processor to convert SVG to XAML
Object returnVal = HtmlPage.Window.Invoke("svg2xaml", svg);
if (returnVal != null)
{
string xaml = (string)returnVal;

Canvas canvas = (Canvas)XamlReader.Load(xaml);

double scale = Math.Min(640.0 / canvas.ActualWidth, 480.0 / canvas.ActualHeight);

ScaleTransform scaleTransform = new ScaleTransform();
scaleTransform.ScaleX = scaleTransform.ScaleY = scale;
canvas.RenderTransform = scaleTransform;
canvas.RenderTransformOrigin = new Point(0, 0);

canvas.SetValue(Canvas.LeftProperty, (mapCanvas.ActualWidth - (canvas.ActualWidth * scale)) / 2);
canvas.SetValue(Canvas.TopProperty, (mapCanvas.ActualHeight - (canvas.ActualHeight * scale)) / 2);

mapCanvas.Children.Clear();
mapCanvas.Children.Add(canvas);
}
}
catch (Exception ex)
{
mapCanvas.Children.Clear();
TextBlock text = new TextBlock();
text.Text = ex.Message;

mapCanvas.Children.Add(text);
}
}


Demo:
You want to see something cool? Here is the Live version of the silverlight application served via Silverlight streaming. You can download the following test SVG files locally and then load them into the live application by clicking on "Load Graphics" and selecting the local SVG file (Wikipedia has tonnes of public SVG graphics).




Caveats
The XSL transform is not perfect. Some SVG files might error out during conversion. It works well for most SVG files created with Inkscape which stick to mostly Paths and use linear or radial gradients.

Also, even though the above javascript code tries to be cross-browser it does not work very well outside IE and FireFox. IE works the best with this code. Even Firefox doesn't work completely because the XSL transform applied is slightly different than IE. The XSL transform behavior is so different in Opera that many of the sample SVGs above don't even work. Safari didn't even come to the transformation part of the javascript.

Please consider this as a proof of concept. I will be posting updates to the SVG2XAML XSL and the Javascript code as I figure out how to fix these problems.

Final Thoughts
So there we have it. The ability to load SVG graphic files from a Silverlight application and that too dynamically at runtime. What use is it to load the SVG file dynamically at runtime by doing conversions in the client side? Think Live Game Map Editors...

Thursday, July 9, 2009

Silverlight for games

Target set. Weapons chosen

What sort of game do I want to build?
Even though this blog is quite recent, I have been thinking about the kind of game I want to make for a long time. I asked myself - "What do I miss in games these days?". Then I knew what I wanted to build. A simple 2D adventure game with a deep plot line. A game simple enough that anyone can pick up and play. A game that packs entertainment in a nice little package so that you don't have to invest 40-80 hours to finish it.

A game where the story is central and the graphics and game play are just elements that help in telling the story. A game which someone shouldn't feel bad for giving up a good book for (OK -I might be setting the standards too high here)

Weapon of choice?
Having decided what I wanted to build I started thinking of the tools I want to use to build the game.

My initial choice was XNA and it was an obvious choice for games. I have been dabbling with it and was quite excited about being able to deliver games on the Xbox 360 through the Community Games channel. I had even figured out the toolset with Paint.NET for pixel art and a custom Game Map Editor like the Xna Map Editor and even looked at SilverLua for game scripting.

Then I started looking at WPF for the Game Map Editor since it was much easier to get traditional UI as well as 2D graphics needed for the map editor(instead of hacking XNA with WnForms). This is when something clicked inside me. Suddenly Silverlight which shares its API with WPF seemed to be a really compelling option.

Silverlight vs XNA

Advantages of XNA
1. Ability to deliver the game on Xbox360(or the Zune). There is no other way to do this currently without XNA.

2. XNA is built for games. Silverlight on the other hand is not. There might need to be some adjustments made and some performance/features sacrificed owing to this.

Advantages of Silverlight
1. With the little info available XNA community game sales, it seemed to be not that exciting after all. I felt more and more that PC was a bigger delivery platform especially given the nature of the game. I had better chances of delivering it to a more casual audience through the PC than the Xbox. For this Silverlight is much better suited than XNA since I don't have to worry about installation, runtime redistribution issues in Silverlight like I would have to do with XNA.

2. As an added bonus I can potentially get the game delivered cross-platform to Mac and Linux if I used Silverlight (Even though I am not sure how open Mac and Linux users are to an Microsoft technology)

3. In game UI can be greatly simplified by using the Silverlight controls but at the same time have the flexibility to "skin" the UI to make it look more exciting in a game environment

4. Making the game experience more social by integrating with social networking sites(like Facebook connect) is much easier with Silverlight game delivered on the web. This opens an entirely new avenue to explore.

5. Containing piracy on PC would be easier with Silverlight than XNA (Or so I hope. Theoretically it would be possible to get the Silverlight code and find a way to hack it and run it offline)

6. Delivering the game solely through the web also opens interesting monetizing options.

7. The Roadmap for Silverlight with Silverlight 3.0 and beyond like Out of Browser experience and GPU accelerated graphics is quite exciting.

So there it is. I've decided to use Silverlight for my adventure game.

An intersting side effect of chosing Silverlight is that I started to increasingly consider Vector Graphics for my game instead of raster graphics since WPF/Silverlight 2D API is more vector graphics based. The main advantage in my mind is cleanly scalable graphics and resolution independant games (Consider playing a silverlight game full screen. Scaling pixel graphics would make it blocky or too fuzzy after filtering to avoid blockiness). I have looked at using the cool and free tool Inkscape for SVG graphics that can be converted to XAML and used from Silverlight(More on this in a later post)

Flash?
People might ask me why I didn't consider Flash at this point. It has all the advantages of Silverlight as well as much wider adoption across machines and platforms. The main reason is I like the productivity I get on the .NET platform over ActionScript or whatever new environment I have to get used to.

Also the installation of Silverlight on Windows takes less than 20 seconds and I don't think that should be a big barrier if the game turns out to be good after all. (I am not sure of the experience on the Mac and Linux but something I will be looking into).

And again the roadmap/rumors on Silverlight on Mobile platforms(and Xbox360?) makes me think Silverlight might not be bad after all in the longer run.

iPhone?
Everyone wants to get their game onto the iPhone. It seems to be becoming the defacto mobile gaming platform that is open enough to be easily developed for. At this point I am going to concentrate my efforts on the broader PC base and probably revisit iPhone development at a much later time(once my game is successful?). For now I am just making sure I am not basing any of my game data directly dependant on Silverlight(like using XAML) so that it can be more easily ported to other platforms. Who knows? Silverlight might be ported to iPhone even.

So that's it. I have decided on the game to be built and therefore the technology to use based on my target platform.

This post has become much longer than I anticipated. Please feel free to post your comments here if you disagree(or agree) with me on any of the above things.

Update(July 10th, 2009) : Silverlight 3 has been released

Tuesday, July 7, 2009

Why get into Indie game development? (or Why Not)

This is not the first question I asked myself when I thought of making games and I suspect it's the same with so many of you thinking of getting into it.

But I think it's an important question to ask early. Again I haven't done anything at this point and so I am not trying to give advice or answer any questions. Just putting down my thoughts here.

For me the "Why Not?" question is the easier one to list. It follows logic more. "Why?" is probably more emotional (This is turning out to be a recurring issue in my life - "Do I want to go back to India?"). And by putting them down it should be perfectly clear to anyone why you should *not* get into independent game development.

Why Not?
1. I already have a good paying job which takes a lot of my energy
2. The game market is saturated with too many games - high budget and independent
3. Because of 2) the money you can make in games is low and way less than what I currently make in my job
4. The chance of failure is lot more than success

Why?
1. Because I really want to make games (if not, just stop right here)
2. I am my own boss. I decide and control the outcome(at least I feel I do)
3. Satisfaction with work is high. Work is no longer a bad word (is that good for my personal life though?)
4. Applying creative ideas at levels unprecedented in my current job

At this point my friends might tell me - "You should join a start up". Some of them are in one and they seem to get 3), 4) and some of 2).

But I guess it all finally boils down to 1) - Why do you want to make games? This is where things cannot be put down on paper. At this point I am probably comparing myself to an artist who likes the art. But then there is this extra thorn in my subconcious - I am not even sure I am good at the art.

I am not sure of any of these things and it is this uncertainity which leads me to treat it like an adventure. And I could just stop it all one day and go back to my cozy life - Forget I even went on an adventure. Which is where I hope this writing will help me - Not to put down some memories but to remind myself that there is no turning back now...

Sunday, July 5, 2009

Why this blog

I am setting up this blog so that I can chronicle and share out my experiences in trying to become an independent game developer.

Right here is step 1.

The other purpose of this blog is to share out information on specific technologies/ideas that I have been playing with in creating my games - Aggregation of information I found on the web or things about which I haven't found enough information on the web where I would like to fill the gaps in.

Also my hope is that this blog would be a place where I would announce progress and completion of my games and the lessons I learnt on the way.

And finally the name of my blog "indie-indian" - Is to probably just identify myself with the sub-minority group that I am in - The Indian independent game developer. Maybe there will be some posts on this, trying to reach out and connect with others in this group. Maybe if I become successful I can get more people into this group...