Virus X Monogame/UWP Port

I finally finished porting an old classic of mine from XNA to Monogame and into the Windows 10 store: Virus X, a colorful party game like arcade game for up to 4 players.

You can find the source, more description and download links on github.

Why port?

  • Couldn’t do any fixes anymore because XNA only works with old Visual Studio versions
  • User needs to install redistributables
  • Difficult to put in Windows Store

A few notes on the difficulties during the port:

  • I tried the whole thing two years ago already, Monogame has grown a lot since then, so they were not a lot of obstacles
  • Shaders needed some extra care..
    • XNA is DX9 but Monogame is DX11, so all shaders were previously model 3. ps/vs_4_0_level_9_1 usually did the trick, but there are some minor differences
    • The single most complicated thing was Texel/Pixel offsets:
      All particle movement in VirusX is computed on the GPU using textures for their data and pixel/vertex shaders since DX9 didn’t have Compute Shader (you can’t use them with Monogame despite it using DX11 since Monogame is still extremely close to XNA4 😦 ). However, pixel coordinate systems are different in DX9 and DX10/11! MSDN provides a good overview here.
      By the way: As if the Compute Shader limitation wouldn’t be enough, XNA/Monogame has no point drawing. To add new particles to the data textures without perform a blocking read + write (no async read/write!) I needed to draw single-pixel wide lines.
  • All Asset settings need to be ported manually. Not a big deal with Monogames Asset Library tool though.

And for UWP (Universal Windows Platform == Windows 10 Store):

  • SharpDX.MediaFoundation.dll and thus Monogame.MediaPlayer does not work! You need to port all your music playing to something else.
    • I used Windows.UI.Xaml.Controls.MediaElement which is quite easy to use.
  • Your window is always resizable. This led to quite some headache in Virus X which relied on resizes only in the options menu. Doesn’t work everywhere properly. You can kindly ask the UWP view for a preferred min/max window size (ApplicationView.GetForCurrentView().SetPreferredMinSize(...)), but that didn’t work for me at all.
  • File access in UWP is very restricted (in a good way from the user’s perspective) and you’ll find yourself suddenly without your favorite .NET file functions. Also, most of it is async.
    Luckily I didn’t have a lot of them in there.
  • XML reader apis are different but quite similar
  • Localization…
    The original used resource files (resx) for strings. These files generated a class that provided all the strings. There is a very similar mechanism in WinRT, but it it differs in the details. The resource file (resw) has the same format but needs to be in a given folder structure. There is no class generated, instead a Windows.ApplicationModel.Resources.ResourceLoader will always provide you with resources for the current app language. Setting the app language proved surprisingly tedious. Without discussing the details here, I’ve ended up with this code:

    var culture = new CultureInfo(value == Languages.English ? "en-US" : "de-DE");
    Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = culture.Name;
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;
    Windows.ApplicationModel.Resources.Core.ResourceContext.ResetGlobalQualifierValues();
    var loader = new Windows.ApplicationModel.Resources.ResourceLoader();

    The switch from generated class to something like VirusXStrings.Instance.Get("MyString") was quickly done via a regex-replace. I considered using a dynamic class to keep the “member semantic” of the previously generated code, but after some problems I decided against it.

Submitting to the store itself is pleasantly uncomplicated. Just use the export package function from Visual Studio, create a store page with a Microsoft account and work through all the various options of a submission.

Once submitted, you can even see usage statistics and crash reports. However, the crash reports I got in so far didn’t help me fixing their causes – apparently there is some loading issue on startup on some machines.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s