A couple of posts ago I wrote about how my expectations for the new release of Galactic Wars 3 were higher than ever. I also said that it continues to surprise me how many people download each version despite there being only a few functionality additions and enhancements. Well this release has not been any different. Since midday Monday until the writing of this post, Galactic Wars 3 v1.2 has been downloaded over 1520 times. In total, GW3 has been downloaded over 5 000 times since around May 10th. Not too bad for someone whose previous game was downloaded a mere 2600 times over the course of a few months.
Well all of this got me to thinking about the future and about how I want to distribute games. The current model just isn’t working. People have donated, but the numbers do not lie. More people rather download the game, mirror it without approval, change it, and god knows what else with it than donate to my cause and then do those things. And the reason is clear, why give a few bucks of your hard earned cash for something you can get for free from the same place? Well hopefully that will change in the future, but as of now, I can’t promise anything to anyone (not even myself). All I know is that if I had $1 (donation!) for each download of GW3, I would be a lot better off and could take time off to make more games.
At this time, I would like to thank those who did take the time and effort to donate, no matter the size:
How come (in Vista) deleting files seems to be broken? The OS likes to decide that an application is still referencing a file that I am trying to delete, thus elevating to admin control. I hit continue, say yes, I am sure I want to do this and still nothing happens. Vista decides that it still can’t delete the file. This is great if I am using the file somewhere, but generally I am not when this happens. I can open the folder, select the files and delete them without elevation. I can then step back up a directory to the one that did elevate and delete without a problem.
So why didn’t it delete in the first place?
One of the tasks I had recently was to get not only a web page into a SharePoint page but also pass in parameters from the Query String. Let’s say I am going to create the page at http://localhost/sharepoint/mypage.aspx in a normal way. In order to host a page inside that SharePoint page, we can use a Page Viewer Web Part, but this limits what can be done. Instead, we can create a custom web part to do the work…
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class CustomWebPart : WebPart { public override void Render(HtmlTextWriter writer){ string rawUrl = Context.Request.Url.OriginalString; int index = rawUrl.IndexOf("?"); string query = String.Empty; if(index != -1) query = rawUrl.Substring(index); writer.Write( "<iframe src='http://localhost/sharepoint/myOtherPage.aspx" + query + "' width='100%' height='765px'/>" ); } } |
And in the category of amazingly awesome photos…
No, I did not take this. Wasn’t even alive at the time.
I do not understand why the difference between ASP.NET and PHP hosting is so gigantic. They are completely different beasts and I understand that most if not all hosts running ASP.NET are using Windows Server to do so, but why are the packages and reliability so different? It doesn’t make sense to me that on a PHP host you can get the same reliability as an ASP.NET host for the same price with one major difference: the PHP host gives you gobs of bandwidth and space. Here are some hosts and what I have experienced so far (from worst to best)…
WebHost4Life
ASP.NET, PHP, etc. and Unlimited Bandwidth
WebHost4Life was one of my first ASP.NET hosts and was used largely because I could run PHP alongside my normal web apps. This is a huge plus since I run a PHP-based forum and did not want to force my users to recreate their users, et cetera. So what was the problem with WebHost4Life? Daily downtime of an hour or more at roughly 2AM GMT -5 due to the AppPool being reset. This is completely unecessary and about the worse thing a host could ever do, especially when claiming 99% reliability.
BlueHost
PHP, unlimited everything
BlueHost was my first real host and I have had my account for over two years now. What can I say about them other than they are amazing, especially for Shared hosting. I am running three sites on them now and am having no problems so far with scalability. But because accounts are so cheap compared to ASP.NET hosts, I can easily buy a second or a third if need be. Only problem? The CEO has told me in a private e-mail that he will never support ASP.NET on BlueHost, ever. Saddening because they could do great things for the ASP.NET world.
Reliable Site
ASP.NET, PHP
Reliable Site has been a great host for me up until recently. They were always great on support and always willing to help me out. Reliability was top notch: I didn’t experience a single second of downtime on my Clustered account, even when hosting four sites. The problem? They expect you to pay $8 a month for a mere 40gb of extra bandwidth on a rolling schedule. That means that bandwidth isn’t calculated per month but per last 30 days. This may be nice if you have consistent days, but spikes can ruin your bandwidth for 30 days. You have no chance of timing a release for the last 2-3 days of a month because it won’t matter.
I have experienced other hosts but they really aren’t worth mentioning. I just wish I could find a host that did what ReliableSite does but was easier on the bandwidth pricing. Especially when DreamHost, BlueHost and several others offer 5tb and more of bandwidth per month for less money.
I am still being surprised by how well Galactic Wars 3 has been received by the communities, both XNA and Zune. I of course have my internal goals for each release which includes how many downloads it must achieve before a second release is deemed really necessary. But also how fast it achieves this goal and how it does this relative to the last release. For example, over all the releases so far I have tracked that it has been downloaded from my servers well over 3000 times. Having been released for about 16 days, this means an average of 187 downloads per day on the item. Not bad considering the last item, Domination, was downloaded a mere 2600 times over the course of 4 months.
Today I released a new version of the game and it has already met my expectations for the day. Despite raising them, I am still taken back by the amount of downloads a mere update generates. I guess it goes to show that when push comes to shove, people want new simple features over the world’s greatest game. I have come to this conclusion based on a few factors, including that the past two releases have been some of the fastest downloaded and contain the biggest small feature enhancements like new levels, new enemies or a high score list.
Hopefully my other games can meet ever increasing expectations since I have no raised the bar somewhat for myself and other Zune developers.
After you have downloaded all the software (for XNA) and have a killer idea, it is time to actually learn how to draw something on the screen–right? How do you expect to make a real game without drawing anything? This tutorial shows you how to use the SpriteBatch object to efficiently draw 2D items on the screen. In the end you will be experienced with rotations, scaling, sprites and sprite sheets. So let’s get started!
Every once and awhile I find the need to get a reference to a Type maintained in a separate assembly. This tends to happen when I am loading assemblies at runtime and am trying to build an instance of a known Type in that assembly. In fact, this is how my XmlProvider class builds instances. Well I have found that the built in System.Reflection.Emit.TypeBuilder.GetType(…) method does not deal well with these advanced situations. So here is a very inefficient, brute force method for getting the Type object you need. Also note that I have included some tags for cross-platform compatibility. I am still looking for a workaround for the Zune and Xbox 360.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /// <summary> /// Handles cross assembly type referencing by searching loaded assemblies for a type. /// </summary> public static class TypeBuilder { public static Type[] GetBaseTypes(Type type) { List<Type> types = new List<Type>(); Type t = type; while (t.BaseType != null) { if (t.BaseType == typeof(Object)) break; types.Add(t.BaseType); t = t.BaseType; } return types.ToArray(); } /// <summary> /// Gets the Type object for a specific type name. /// </summary> /// <param name="typeName">The type name to search.</param> /// <returns>A Type object.</returns> /// <remarks>Searches assemblies only loaded in the current application domain.</remarks> /// <seealso cref="System.Reflection.Emit.TypeBuilder"/> public static Type GetType(string typeName) { #if ZUNE return null; #else if (String.IsNullOrEmpty(typeName)) throw new ArgumentException("Provided type name was invalid."); // Get a list of assemblies first... Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); // Loop through until we find the type. foreach (Assembly assembly in assemblies) { Type t = assembly.GetType(typeName); if (t == null) { Type[] ts = assembly.GetTypes(); foreach (Type type in ts) if (type.Name == typeName || type.AssemblyQualifiedName == typeName) return type; } if (t != null) return t; } // We may need to fall back on the built in builder. return System.Reflection.Emit.TypeBuilder.GetType(typeName); #endif } } |
This tutorial is dedicated to those who are new to the world of XNA. It is meant as a very small primer for understanding Visual Studio and how XNA games are developed. After installing Visual Studio 2008 (or C# Express 2008), DirectX 9.0c, and Game Studio 3.0 (currently CTP), open up Visual Studio. If this is your first time opening the software up, it will probably ask you what kind of settings to use. I recommend C# settings, but don’t worry because the layout is completely changeable. Once the IDE (Integrated Development Environment) is done processing we can create our first "game"!