A View Inside My Head

Jason's Random Thoughts of Interest


The Impact of Localizing a Windows Store App

Recently, I had an idea for an experiment to see what kind of impact localization had on app downloads from various markets. One of my casual games for Windows 8 and Windows Phone 8.1 (Piano Tap) had decent momentum in English-speaking markets, but not a lot of activity elsewhere.  So, I put out a call for assistance to help translate strings into new languages.

Many thanks to those who contributed: David Nielsen (Dansk), Hervé Thouzard (Française), Kenneth Truyers (Nederlandse), Sara Silva (Português), митрий Кульшицкий (русский), and Seth Juarez (Español). Note: I’d love to include even more languages or regional translations, if you have something to contribute (especially non-Latin languages).



Piano Tap is a Windows Universal App written in HTML5/JavaScript. Since I had written Piano Tap entirely in English, strings were embedded in the app a couple of different ways and some refactoring was necessary to prepare for localization.

Some strings were embedded directly in the HTML itself, like the text for the “Play Again” button:

<button data-bind="click: replay">Play Again</button>

To provide translations, I needed to extract these strings into a resource file (more on that below), and then use a WinJS data-win-res attribute to indicate the string’s resource ID to be used as the source for the button’s text content:

<button data-bind="click: replay" data-win-res="{textContent: 'play_again'}"></button>

Note that for the app to crawl the HTML and make the necessary substitutions, you must call WinJS.Resouces.processAll() (I did it in the handler of the Loaded event of WinJS.Application):

app.onloaded = function () {

Other strings were embedded in the JavaScript code, like the object literals that contain configuration for the game and menus:

{ id: 'NeedforSpeed', name: "Need for Speed", max: 50, ...

For these, I used the WinJS.Resources.getString(id) function to retrieve the string from the resource file:

{ id: 'NeedforSpeed', name: WinJS.Resources.getString('NeedforSpeed').value, max: 50,




Resource Files

For each language being translated, you will need to create a folder and a resources.rejson file in your project. Since my app is a Universal App, I did this in the Shared project:


At runtime, the user’s machine will try to find a resource entry that is as close as possible to the current culture code. For example, someone in Australia will likely have “en-AU” as their current culture code. If I had provided a resources.rejson for en-AU, then those strings would be used. Since I didn’t, it will look for a neutral culture for that language (just “en”). And, it appears that if a neutral culture does not exist, but an alternative locale does for that language (such as “en-US”), then it will choose that resource.  Such is the case for Portuguese in my app, where I have a resource defined for the locale pt-PT, but this is used by machines in Brazil (pt-BR) as well instead of reverting to the the app’s default of en-US.

A resources.rejson file contains a strict form of JSON with key/value pairs:

    // Button label to take the player back to the menu screen
    "menu"                      : "Menú",

    // Button label to restart the game that the player just finished
    "play_again"                : "Jugar de Nuevo",

    // Button label to share a high score with other people
    "share"                     : "¡Compartir!",

    // Name of a game. Comes from a movie quote in Top Gun "I feel the need for speed!". 
    // Can be translated as "Need to go very fast", etc. In the game, the player must 
    // tap as fast as they can to get to the end.
    "NeedforSpeed"              : "¡Necesidad de Velocidad!",

    // Instructions to the player displayed before starting the game
    "NeedforSpeed.Description"  : "Correr hacia 50 sin tocar los azulejos Blancos",


The key is the Resource ID, which is used by WinJS to locate the strings (see the “How” section above).  The value part is the translated string itself. By suggestion, I added comments to the file in order to provide hints to my translators about the meaning of each string, since a lot of times, slang or colloquialisms will not have a direct equivalent in a different culture.

In addition to the strings used within the application, I also discovered that you will need text used in the app store listing to be translated as well (more on this in the next section). I simply added these at the bottom of the resource file as comments so that I could just copy/paste when needed:

// Also need these for the store listing:

// "Tap your way through songs as quickly as you can by only touching the black tiles as they scroll past. Sounds easy enough, right?"
// "Pulsar a través de varios canciones rapidamente solamente tocando los azulejos negros. Suena fácil, ¿no?"

// "Three different games"
// "Tres juegos diferentes"

// "Piano and simple beep sound effects"
// "Piano y bips simples"

// "Three different games, and your choice of piano notes, a simple beep, or no sounds."
// "Tres juegos diferentes y la opción de notas de piano, un bip simple, o la ausencia de sonidos."

// "Click only on the lowest black cells. How fast can you go?"
// "Hacer clic en las celdas negras más bajas. ¿Qué tan rápido puedes ir?"

// "If you click a white cell, then the game is over."
// "Hacer clic en una celda blanca causará el fin"

// "Touch screen works best, but mouse and keyboard are equally supported"
// "Las pantallas táctiles funcionan mejor pero tambien soporta ratón y teclado"


Store Listing

So far, localizing my app was pretty simple since I just needed to do string replacements. Even if I had images that needed to be localized, I feel that it would be a pretty straight-forward process that would not take a lot of time to retrofit. What I was not prepared for, though, was how tedious the store submission process was once you added multiple languages.

Note: If you’re reading this, MSFT folks in charge of the Store, I would *love love love* to see something like having special key/values in the resouces.rejson file be used to auto-populate the store listing for each language.

Essentially, each culture requires its own store listing.  When you upload an appxbundle package, the store will detect all of the languages and require you to provide descriptions, screenshots, etc. for each of those languages (sometimes, twice for a given language – once in the neutral code, and once in a default locale for that language such as “Spanish” and “Spanish (Spain)”). 

If you later add an additional language, it will appear as “Not Started” in the Description step, preventing you from submitting your update until the required information is provided.


This is where docking Visual Studio and my web browser side-by-side proved handy, since I could then just copy/paste as needed:

Screenshot (54)

Notice that I said above that screenshots are required for each language, which just makes sense since I would not want to see an app listing with screenshots in Chinese or some other language that I could not read. To capture a screenshot in another language (and for general testing in general), you will need to temporarily configure your machine to use that language or culture code.

First, add new languages to your machine using the Language Control Panel:


Then you can change the order of the languages to place the one you need at the top.  Launch your app, and the strings will appear translated.  Note that this is also useful to browse the Windows Store in other locales (to see your app’s store placement in the Top lists, etc).


The Impact

So, what has the impact been for these new languages?  Is it noticeable?

Since I use MarkedUp to provide some analytics and crash reporting for my apps, it is easy to see the installs by country over time:


It’s very clear on these spark graphs when translations were added for France, Belgium, Russia, Netherlands, and Portugal. Other countries where I would have expected a bump (such as Brazil) produced only a minor enhancement.  Note: The Spanish translation was just added today, so I’ll be watching over the next few weeks to see what impact that has for Spanish-speaking countries.



Localizing an application is not a trivial process, even though my experiment was just simple string translations. You need to find translators who understand both your native culture as well as their own culture so that the resulting localized text is appropriate to the context. Even though I had volunteers from the community to assist me, this will not always be the case and professional services will likely be required.

In addition, you need to consider things like date and number formats, as well as left-to-right versus right-to-left languages.  If you use iconography, know that certain symbols are not universal (for example, a Stop Sign in the USA is a red octagon with a white border, while a Stop Sign in Japan is red triangle with a white border).  All of these things combined are necessary to completely localize an app. However, localization of your app will certainly be appreciated by users in those other locales. 

Before taking on the effort, it is wise to consider the return on your investment. My experiment showed a definite bump in France, who all but ignored the app before I provided a French version (but now, it is #1 within its subcategory, and continues to move up in the rankings for Games in general). But, is the audience in France large enough to justify the time required and any necessary expenditure that may have been needed to perform the localization? These are hard things to estimate without actually taking the plunge.

The conclusion for me, personally, based on this experiment is that the bump in downloads due to translation is not worth investing money upfront (especially for a free app that only makes tens of dollars in ad revenue).  Perhaps for a different app, maybe a Top 25 in its category with tens of thousands of downloads where every 100 additional users produces a measurable increase in ad revenue, would I consider going through the effort again (and even paying for it this time!). 

But, for now, I’ll just continue to dream of having an app that proves to be that popular… and save my money for the next burrito at Chipotle.

Can You Help with Translations?

I’m localizing one of my games to understand (and eventually write about here) the process involved and whether it impacts downloads from various markets.  I selected Piano Tap for this experiment, mainly because it has a lot of download momentum at the moment from around the world, and there’s only 24 33 strings total that needed to be translated.

What I’m asking: If you are a fluent speaker (and hopefully, also writer) of a language other than US English, then please help to provide a translation for that language.

What is involved: Download a text file (resources.resjson), edit with a text editor (i.e., Notepad), change the English text on the right-hand side to your language’s translation, save, and email it to jason@jasonfollas.com. Please also let me know the language that you used, in case it’s not obvious to me.  Smile  Total time that I estimate is under 15 minutes.

What can I offer you in return: I will include your name in the game to give credit for the language (when the user’s culture uses your translations). At the bottom of the file is this line:

"TranslationBy"             : "{English} translations courtesy of {Your Name}"

Simply change “{English}” to your language name and “{Your Name}” to your name.

How do you start: You can download the resources.resjson file here: https://drive.google.com/file/d/0B-4nO3eLggf9Wm8td1ZETXEtd2s/edit?usp=sharing

Update: Per a comment from one of the translators, I have added comments to the file to better describe the context of the text to be translated.

Languages already translated:

  • Dansk
  • Française
  • русский
  • Nederlandse
  • Portuguese (pt-PT) NOT pt-BR
  • Español


It’s fascinating for me to see something that I wrote be presented in a different language!

Screenshot (43)

Self Promotion: My Games

As a web developer by trade, I find the ability to create an application using HTML5, CSS3, and JavaScript to be very compelling. In my opinion, Microsoft did a fantastic job of offering this as one of the language choices for developing Windows Store apps – you get native packaging of your web assets into an application that can be sold in an app store without needing to use a webserver, or a hybrid app container like PhoneGap, etc. 

I took advantage of this to write a handful of games that have been published.

Logo Image: Knave Defender   Logo Image: Knave Blackjack

Logo Image: Knave Craps   Logo Image: Knave Slots

Logo Image: WuX   Logo Image: WuX Defender

Knave Defender

The very first game that I wrote for the Windows Store was Knave Defender:

This game started out with the concept of being part of a larger Blackjack trainer – a series of mini-games intended to build skills needed for playing Blackjack. This particular mini-game was intended to strengthen the ability to quickly sum up a hand. The goal is to build a hand of 21 before an invading UFO lands (to destroy the ship). If you bust, then the invader escapes. If the invader lands, you lose a life.

Being my first game, I didn’t know when to stop adding things to it.  The original Knave Defender had a full soundtrack and sound effects (that I purchased rights to for about $50 total). It had multiple levels. It had a menu, and a pause mode, and configuration options.  And, after a year and a half of being in the store, it has only 189 downloads.

Just this week, I rewrote Knave Defender as a Universal App with the intention of releasing it for the Windows Phone, too. I stripped out a lot of the extra cruft, and turned it into a simple repeating invader game. Keeping with the original vision of being a Blackjack trainer, I disabled the display of the hand’s sum so that the player has to do that part in their head.  I also added a global leaderboard so that your high scores can be compared to other players from around the world.

Screen shot 1


Knave Blackjack

The first step to submitting an app to the Windows Store is to reserve a name for the app. As you can imagine, “Blackjack” was quickly snapped up by somebody out there, so I had to come up with another interesting name.  So, even before Knave Defender was released, I had the name “Knave Blackjack” reserved for this game.

Knave comes from a card that existed in the deck of playing cards before the Jack card was added. It was of the same rank as a Jack card today. One reason for its replacement was because the Knave’s index was “Kn” and was often mistaken for a King (“K”) in a fanned out hand held by a player.  So, in some ways, “Knave” is a synonym for “Jack”, and that’s why I use it today for all of my casino-related games.

The idea to write a blackjack game came from a presentation that I gave at Devlink with Mike Eaton. We were doing a parity talk to show how a Windows Store app would be developed in HTML/JavaScript (my preference) versus XAML (Mike’s).  Not wanting to do another To-Do list as the demo, we decided on using Blackjack as the theme instead. My part of that demo eventually morphed into Knave Blackjack:

Screen shot 1

I fell in love with CSS transforms while writing this game, and made the view of the table something that the user could control (panning, tilting, and zooming are all accomplished using touch gestures that change a style on a DIV).  I also designed the table to be skinnable for a marketing idea that I have yet to bring to fruition.


Knave Craps

For me, the best game in a casino is Craps, so I just had to follow up Blackjack with a realistic Craps game. A casino opened up along my daily drive home, so I had a place to play (I like to call that “research”) in order to observe how the dealers handle bets and payouts. After a few months of work, Knave Craps was released:

Screen shot 1

Writing Blackjack had taught me that people inherently do not trust Random Number generators, no matter how careful you are at trying to ensure random results. People even go so far as to accuse the game of intentionally doing something in order to screw over their bets.  (Their electronic bet, mind you, that cost them no real money to place). The reviews that I get for the Craps game show that the same issues exist.

To mitigate this, I added a feature to track statistics over time to see what the roll distribution is. I also added a feature to have thousands of rolls performed to ensure that the results fit the expected curve. And, to put the player in charge, I wrote the randomizer to shuffle through possible rolls over a 3-second period, allowing the player to stop the randomization at any time. 


Knave Slots

After Craps, I wanted to do one more casino-style game, but I also wanted it to be unique.  I came up with the concept of combining several games into one: Slots (for randomization), Blackjack, Baccarat, and 3-Card Poker.  The thought was that the slot machine aspect would generate three random cards for the player, and three for the house. The player would place a bet on the winner of any hand (either player, dealer, or tie), and spin the reels.  This game became Knave Slots:

Screen shot 1



At some point while writing the casino games, I started thinking about game theory and how randomization is handled by things like Rock-Paper-Scissors. This introduced me to the RoShamBo, a generalized game that Rock-Paper-Scissors is based on. A RoShamBo has an odd number of elements available, with each element beating half of the other elements (and beaten by half of the other elements). So, in Rock-Paper-Scissors, there are three elements, with each choice winning and losing to one other choice (not considering ties).

Being a fan of the World of Warcraft, I wanted to write a game that used the Elements to form a RoShamBo. Looking for some historical context, I stumbled upon the ancient Chinese Wu Xing (translates as five rows, but it is often taken to mean five elements in Western cultures). This gave me an odd number of elements to work with and rules about which element strengthens or weakens another element.

So, Wood, Fire, Earth, Metal, and Water made their debut in a puzzle/strategy came that I called WuX:

Screen shot 2

In WuX, players take turn placing a random element in a cell. They are blind to what the opponent has placed until both players have claimed the same cell, and then a decision is made using the Wu Xing RoShamBo. The goal is to get three-across (using the center cell), and if that is not possible, then to win more cells than your opponent.

It’s a puzzle in that you are trying to figure out what your opponent has placed where, and a strategy game because you need to keep enough of your elements around to beat their remaining element, especially for the all-important center cell.

WuX maintains a global leaderboard that tracks a cumulative score, as well as the number of wins, losses, and tie games over a player’s career.


WuX Defender

After the rewrite of Knave Defender to make it focused on being a Blackjack trainer, I decided to make a variant of the game using concepts from WuX. Each invader starts with a random element. Instead of cards, the player gets a random element to assign to an invader. The goal is to “weaken” the invader to destroy it, but it’s not always possible, so you have to try to decide how to dispose of elements in order to move on.  Sometimes, this results in strengthening an invader (i.e., adding wood to fire will strengthen the fire).

This game became Wux Defender:

Screen shot 1


What’s Coming

WuX started out as a mini-game in a larger game that I’m currently working on called Amassment. I decided that the WuX aspect made Amassment too complicated, so that’s why it was pulled out into its own standalone game. I’m hoping to have Amassment in the store before Summer 2014.

HTML/JavaScript Universal Apps: A First Look

For me, one of the most exciting and long-anticipated announcements from last week’s //BUILD conference is the upcoming ability to write Windows Phone 8.1 apps using HTML and JavaScript.

As a web developer, I spend a tremendous amount of time every day writing client-side code that runs in a web browser. I have made a huge investment in mastering these skills and keeping up with emerging trends and “best practices”. The declarative layout and rendering languages of the web, HTML and CSS, are widely known standards that for the most part work identically between platforms (albeit, with a few platform-specific idiosyncrasies). So, it makes perfect sense to me that HTML5 is the best solution for writing cross-platform apps.

Windows Phone 8.1, due for release later this month with widespread over-the-air updates happening this summer, will finally have parity with its tablet/desktop siblings in the ability to run WinRT apps.  This app model allows developers to use the language of their choice to develop apps, from C++ to .NET to HTML/JavaScript.

Since Windows 8.1 and Windows Phone 8.1 will share the same app model (as will the Xbox One, it was announced), the natural question is: Can I write my apps once and have them just work on each platform?  The answer, for the most part, is ‘Yes’, using a new solution type called Universal Apps.

Starting with Visual Studio 2013.2, you will find new project types for creating Universal Apps:


Creating a new Universal App project will make a solution with three projects inside: a Windows app project, a Windows Phone app project, and a Shared Code project:


Most of your application’s code will go into the Shared project. But, here’s where reality sets in: because a phone is different than a tablet/desktop, both in screen size, memory, and general platform capabilities, it is necessary to maintain some platform-specific pieces within their own project types.  So, any artifact that exists in a platform-specific project will override the same file from the shared project at build time.

For HTML/JavaScript apps, this primarily means maintaining different stylesheets between projects. But, in my tests, there are a few other things that didn’t “just work” while converting an existing Windows 8.1 app into a Universal App. These differences may require some code refactoring in order to separate the features that are only available on a particular platform from the rest of your shared code.

Incompatibilities that I’ve found:

  • No SettingsFlyout: In Windows 8.1 Apps, settings are maintained within flyouts that are accessed from the Settings Charm. This does not seem to be implemented on the phone, so you will need to find an alternative way for the user to specify settings, and refactor your codebase accordingly.

  • Web Fonts: It is very easy to bring a new font into a HTML/JavaScript Windows 8.1 app using Web Fonts (fonts that are temporarily used, but not installed to the system).  For my Windows 8 tablet/desktop apps, I’ve been using Embedded OpenType fonts (.eot).  This format does not appear to be supported on mobile Internet Explorer 11 (which is what the phone’s HTML/JS app container is based upon).  However, the Web Open Font Format (.woff) does work. [UPDATED]

  • Advertisements: In my Windows 8.1 games that are in the Windows Store, I use Microsoft’s advertising platform to earn a little bit of revenue from an otherwise free-to-play game. The Ad SDK is available for use within the Windows project, but not the phone project. Note: This incompatibility is for HTML/JavaScript project types only. The C# project type, for example, does provide an Ad SDK for phone apps.

  • Audio: My games make use of audio, as you would expect, for things like click feedback, explosions, etc. This is relatively straight forward using the HTML5 Audio element/object. Since I don’t have 8.1 installed on actual hardware, I’ve only been able to test using the Windows Phone emulator in Visual Studio. In those tests, there are severe synchronization issues with HTML5 audio. Sometimes sound never plays, and sometimes there is a lag of a few seconds before a sound finally plays. It seems to be a memory management/caching thing, because once a sound has played for the first time, there’s usually little lag if that same file needs to play again within several seconds. [Confirmed on Device – Nokia Lumia 928, delays exist]

    The issue with audio lag may be how I was initializing the code. For example, to play a sound effect from JavaScript, I’ve been using code in my Windows apps like:
    var sfx_click = new Audio("/audio/menuclick.mp3");
    sfx_click.msAudioCategory = "GameEffects";
    sfx_click.volume = 0.8;

    I found a remark on MSDN that states:
    You must set the msAudioCatogery before setting the src property in code.

    So, I have rewritten the above to now look like:

    var sfx_click = new Audio();
    sfx_click.msAudioCategory = "GameEffects";
    sfx_click.src = "/audio/menuclick.mp3";
    sfx_click.volume = 0.8;

    Though I am still experimenting, this seems to have greatly improved the lag situation (so explosions happen at the appropriate time, etc).
  • NuGet: Integration with NuGet seems a bit weird, if not incomplete. You can add a package to the platform-specific projects individually, but not to the shared project. And, NuGet itself seems to get confused, because even though the package is added to the packages folder, none of the artifacts (scripts, css, etc) get created within the project itself. So, if there’s a library that I need to use in both places, what feels natural is to use NuGet to install the packages, and then use “Add Existing” to include files from the platform project’s packages folder into the shared project… but, this means that those artifacts are not truly maintained by NuGet.  If there’s then an update to the package, then I’ll need to manually repeat the process.

  • Windows.ApplicationModel.Store.CurrentApp.getAppReceiptAsync(): It seems, at least at the moment, that the XML returned from the Windows store differs from the XML returned from the Phone store. Specifically, the Phone document includes a default xmlns on the document element, while the Windows document does not (so, code that uses XPath queries will need to be handled conditionally depending on the platform).
  • Speech API: While converting Knave Craps to the phone, I came across an “Access Denied” error while initializing the Speech Synthesizer. I’m trying to come up with a workaround or find out the root cause.  The line of code that resulted in the exception:
    var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

Sideloading Windows 8.1 Apps

I have created several games for the Windows Store. The process of writing and submitting an app for publishing to the consumer-facing store is well-scripted, with Visual Studio taking care of packaging everything needed into one file, which is then uploaded using the developer portal website, and then finally signed and published by Microsoft’s back end systems.  Once published, the user discovers and installs the app using the Windows Store app on their own machine.

But, what about deploying Line Of Business (LOB) apps for enterprises, which are installed for use only within a corporation (and, thus, are not appropriate for hosting on the public consumer-facing store)?  For now, deploying an application to enterprise machines requires a process known as Sideloading. This can be thought of as the equivalent of manually running Setup.exe in order to install desktop applications, though the requirements and processes involved are different.

First, when building the appx, the developer will need to use a code-signing certificate that links to a trusted root CA since it will not be signed by the Windows Store. The preferred thing to do would be to purchase a code-signing certificate from a company already in the default list of trusted Third-Party Root Certification Authorities (such as DigiCert Assured ID Code Signing certificate).  It should also be possible to use a self-issued certificate that belongs to the enterprise, albeit with a bit of extra work to install root CA certificates onto all of the target machines.

To set the certificate from within the Visual Studio project, simply double-click on the package.appxmanifest file, navigate to the “Packaging” tab, and then click the “Choose Certificate” button.

Next, the user’s machine must have an appropriate operating system.  Side Loading is NOT permitted on the edition of Windows 8.1 that is targeted for home users (known simply as Windows 8.1).  So, this currently means that the user’s machine must be running Windows RT 8.1, Windows 8.1 Pro, Windows 8.1 Enterprise, or Windows Server 2012.

Next, the machine must be configured to allow trusted apps to be installed.  This can be performed using the Group Policy Editor by setting “Allow all trusted apps to install” setting to “Enabled”:


Note: This Group Policy setting simply sets the following registry key: HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Appx\AllowAllTrustedApps = 1

If the machine is running Windows 8.1 Enterprise, and is domain-joined, then it is all set to side-load applications.  Windows RT 8.1 and Windows 8.1 Pro machines must first perform a one-time activation of a Sideloading Product Key, which is acquired using volume licensing channels (sold in bulk, and costs roughly $30 per machine).

UPDATE: Microsoft will be allowing domain-connected 8.1 Pro machines to side-load applications just the same as 8.1 Enterprise. And, side loading product keys will be available for free from volume licensing, or for around $100 from Open License. You only need one product key per organization now, because they're unlimited.  See: http://blogs.windows.com/windows/b/springboard/archive/2014/04/03/windows-8-1-sideloading-enhancements.aspx

To install and activate the Sideloading Product Key on a machine, open a command prompt as Administrator, and then execute these commands:

  1. slmgr /ipk <unique 25-digit sideloading product key>
  2. slmgr /ato ec67814b-30e6-4a50-bf7b-d55daf729d1e

Finally, Windows Store apps are installed per user, so the following needs to be repeated for each user that will log onto a given machine (or automated using Microsoft System Center 2012 Configuration Manager):

  1. Open the Windows Powershell prompt (i.e., type Powershell on the Start Screen and select Windows Powershell from the search results).
  2. Execute the following:
    Add-AppxPackage "C:\path\yourapp.appx"
  3. Visual Studio may have packaged your .appx as an .appxbundle, so substitute that file instead.  As a tip, when copying a file path from Windows Explorer, hold the Shift key when right-clicking on a file, and you’ll have an extra menu item called “Copy as Path” that will include the directory and filename all as one string. This can be pasted into the Windows Powershell window using a right-click.
  4. If the appx has a dependency, such as the WinJS library, then you must include this as part of the Add-AppxPackage command:
    Add-AppxPackage "C:\path\yourapp.appx" -DependencyPath "C:\path\Dependencies\Microsoft.WinJS.2.0.appx"


What can go wrong?

In short, there are a lot of things that can go wrong when side loading apps on Windows 8.1 – probably too many to document in a simple blog post.  However, here’s a couple of cryptic things that we experienced when trying to deploy an app for the first time:

Application would not install.  Error message:

Deployment failed with HRESULT: 0x80073CF9, Install failed. Please contact your software vendor. Deployment Add operation on Package … failed with error 0x8007000D.

Diagnosis and fix: It was found that JavaScript libraries that were installed using NuGet were saved using a Windows 1252 encoding.  HTML/JS apps need to have their JavaScript files saved using a UTF-8 with BOM encoding so that the scripts can be precompiled. 

Note: If Visual Studio 2013 is installed on a machine, then the appx would sideload just fine (resulting in me repeating over and over “But, it works on my machine!”) Without Visual Studio installed, this very descriptive error was encountered when my client attempted to sideload the appx.

To correct this, open each .js file in the Visual Studio project, then choose the “Advanced Save Options” item in the File menu.  Change the Encoding to “Unicode (UTF-8 with signature) – Codepage 65001”, then click “OK”.  Save the file, then rebuild the project.


Note: Running the appx through Windows App Cert Kit (WACK) will also point this out, but in my case, I had updated a NuGet package and thought I could get away without running the WACK tests again since they had previously passed, and my app was working just the same with the new updates.


Application installed without error, but would not launch. Red X on live tile. Event Log:

/Applications and Services Logs/Microsoft/Windows/Apps/Microsoft-Windows-TWinUI/Operational

Activation of the app …!App for the Windows.Launch contract was blocked with error 0x80073CFC because its package is in state: Modified.

Diagnosis and fix: This is what you will find when Sideloading has not been activated, either because a Sideloading Product Key was not installed, or the Windows 8.1 Enterprise machine is not domain-joined. 

For testing purposes, a developer or outside organization may have Windows 8.1 Enterprise from MSDN installed, but not domain-joined.  You cannot obtain Sideloading Product Keys from MSDN, so in order to test sideloading, that machine will need to be joined to a domain.  What I did for my standalone development machine (running Windows 8.1 Enterprise) was to create my own Active Directory on a Windows Azure virtual machine, and then perform an offline domain join using djoin.exe (http://technet.microsoft.com/en-us/library/offline-domain-join-djoin-step-by-step(v=ws.10).aspx).

A View Inside My Head | Jason's Random Thoughts of Interest

A View Inside My Head

Jason's Random Thoughts of Interest


Knave 21 (Blackjack): The Fairness of Random Cards

Blackjack is one of my favorite games in the casino.  I'm a casual player, and certainly not an advantage player by any means.  To help me drill basic strategy, especially for things like soft hands and splits, I decided to write a version of Blackjack for Windows 8 and make it a game that *I* would like to play.  Since I'm not a high-roller, I also wanted to simulate the bankroll that casual players might use in an actual casino: $500 buy in at a $10 minimum table.

Thus, Knave 21 (soon to be renamed Knave Blackjack) was born after a couple of hundred hours of work in the evenings and weekends (the version in the Windows Store represents the third rewrite, and a version currently in development has undergone major refactoring recently as I prepare to add more features in the near future).  It's been a labor of love, and I hope that the attention to detail reveals that.  I've received a lot of positive feedback, and, recently, some negative feedback as well (which prompted this blog post).

One thing that every card game author likely struggles with is how to randomize the card selection so that it's fair to the player.  Knave 21 has the concept of a shoe, which is 2-6 decks of cards that are shuffled together.  It penetrates much deeper than a real casino (the reshuffle automatically occurs when 12 cards remain in the shoe), but the randomness of the deck is very dependent on whatever pseudo-random number generator can be coded in JavaScript.

Instead of relying on JavaScript's Math.random() function, Knave 21 utilizes the Alea library by Johannes Baagøe to provide a better distribution of random numbers.  And, since the shoe is serialized and saved to roaming storage (so you can resume a game on another computer), I didn't want to pre-shuffle the shoe.  Instead, a random card is selected and removed from the shoe upon demand.  If someone were to view the roaming state data, they could see what cards were left in the shoe, but not what the next card would be.  

More importantly (and in response to some recent negative feedback), the game doesn't care what cards have been played or how much you are betting when determining the next card - it simply picks a random number and that's the card that is drawn.  

I'm very concerned about Knave 21's reputation, especially since I have paying customers now that the app is listed in the Windows Store.  In the interest of openness, the code for the shoe implementation follows.  Note the "nextCard" function for the RNG implementation.

Knave.Shoe = (function (Alea, undefined) {

    var shoe = function (decks) {
        this.cards = [];

        for (var d = 0; d < decks; d++) {
            for (var s = 0; s < 4; s++) {
                for (var r = 0; r < 13; r++) {
                    this.cards.push(new Knave.Card("A23456789TJQK".charAt(r), "HDCS".charAt(s), true));

    shoe.prototype = {
        nextCard: function (facedown) {
            var random = new Alea();
            var index = random.uint32() % this.cards.length;
            var c = this.cards.splice(index, 1);

            if (c.length === 0)
                return undefined;

            var ret = c[0];

            if (facedown !== undefined)

            return ret;
        remaining: function () {
            return this.cards.length;

    return shoe;


Metro: Introducing the Local and Web Contexts

I recently recorded an episode of The Tablet Show with Carl Franklin and Richard Campbell (it will be published at the end of July 2012) where I rambled on about discussed different concepts that are needed to construct a Geospatial Metro-style application.  Since I seem to do more web development these days than anything else, I naturally approached this from a HTML/JavaScript developer's point of view.

The geospatial part is really irrelevant.  I included it because I could speak to the subject matter, and it permitted me to establish some constraints around the otherwise huge topic of writing a Metro-style application.  From the web developer's point of view, though, there are existing JavaScript-based APIs that the developer will be interested in using while writing the Metro application (i.e., jQuery and OpenLayers comes to mind).  

Now, when you write a Metro application using .NET or C++, there's a compilation step that takes place to compile the source code into an executable (EXE and/or DLL).  The executable and any dependencies are packaged into an application package (an .appx file), which is really just a renamed .zip file that contains the files, a manifest, and cryptographic information to ensure that the contents were not tampered with.  Aside from WinRT libraries, everything that is needed to run the application must be included in the package.

HTML/JavaScript Metro applications, by contrast, actually run as a web page inside of an Internet Explorer 10 process.  The source files are stored within the application package, much as they would be on a web server.  But, instead of downloading HTML, JavaScript, CSS, and images from a web server across a network, the resources are retrieved from the .appx file on the user's hard drive (much faster load times, and the application is still accessible when there is no network connectivity).

Metro-style applications built using HTML/JavaScript still have access to the Windows Runtime and can do just about anything that their compiled-counterparts can.  In order to allow such privileged access, however, certain common practices in the web world had to be explicitly prohibited.  Specifically, anything that attempts to inject HTML or script into the DOM of a Metro-style application will result in an exception (to prevent third-party script injection attacks).  More details can be found here: http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx

This safe HTML filtering causes a problem with a lot of existing JavaScript libraries.  So, how is a developer supposed to use such a library inside of a Metro application?  It turns out that in the case of Metro-style applications, Internet Explorer 10 will assume two different personalities: Local context and Web context.  

The application bootstraps into the Local context.  This mode is what you'll find most people talking about when they discuss building Metro-style applications using HTML/JavaScript because it has full access to WinJS (and WinRT). Local context URIs start with the "ms-appx" protocol, and the resources must exist in the .appx file.

The Web context is totally isolated from the Local context, and cannot access WinRT and a lot of other things that the Local context can.  As a result, code running in the Web context behaves pretty much like a normal web application today.  This means that developers can continue using those existing JavaScript libraries that don't work in the Local context!

Web context URIs start with the "ms-appx-web" protocol (if the resource exists in the .appx file), or the "http" protocol (if the resource is to be loaded from a web server).  Specific differences between Local and Web contexts is documented here: http://msdn.microsoft.com/en-us/library/windows/apps/hh465373.aspx

In practice, an IFRAME is used to introduce Web context content into a Metro application.  In this way, the outermost web page runs in the Local context, while the IFRAME's content runs in the Web context.  It's possible for the IFRAME to be styled to fill the entire screen, if needed (and the outermost web page becomes just a thin hosting shell).

A common scenario is that data in the Local context will need to be sent to the web context (and vice versa).  For instance, code running in the Local context may listen for events fired by the device's Compass sensor.  When a new directional heading is established, the Local context code will need to send the new data to the Web context code for further processing.

HTML5 defines a means to do this cross-document communication using the window.postMessage() function.  In the case of the new Compass reading, the Local context code would post a message to the IFRAME.  The Web context code would need to register an event listener for the window's "message" event.

The messages themselves are strings, and the developer is left with the task of implementing a data protocol.  JavaScript Object Notation (JSON) will often be used to serialize JavaScript object to a string representation for the purpose of transferring across the contexts (the sending side will use JSON.stringify() to serialize the object, while the receiving side will use JSON.parse() to deserialize it).

The hybrid Local-Web context architecture allows an existing HTML5/JavaScript web application to be converted into a Metro-style application without the need to modify third-party JavaScript libraries.  Though, even after such a conversion, there will still likely be some clean-up needed to make the existing application behave more like a Metro-style application, such as implementing the App Bar for commands, and taking advantage of the Search and Sharing contracts.  But, the reward for going through this effort is an application that can then be distributed or offered for sale on the Windows Store to an audience of millions of potential users.

Want to try these things out today before Windows 8 launches this Fall?  Release candidates are available for free:

Windows 8 Download: http://aka.ms/JenWin8

Visual Studio 2012 Download: http://aka.ms/JenVS2012

Migrating to BlogEngine.NET

I've been wanting to migrate this blog to a different blogging engine for a while now.  So, the other day, while recording an episode of The Tablet Show, Richard Campbell asked me "Did you know that your blog is down?"  

Well, it seems that a recent security patch broke something about SubText as I had it set up on my hosting provider. This became my opportunity to finally spend some time on this tired site!

Entity Framework Spatial: A Real World Example


From the Wikipedia article, Leadership in Energy and Environmental Design (LEED) is described as “an internationally recognized green building certification system, providing third-party verification that a building or community was designed and built using strategies intended to improve performance in metrics such as energy savings, water efficiency, CO2 emissions reduction, improved indoor environmental quality, and stewardship of resources and sensitivity to their impacts.”

In my own words, LEED is a certification system that awards points for following certain environmentally-friendly practices when constructing a building. In the end, a building can be qualify for one of four different levels of certifications, based on the number of points: Certified, Silver, Gold, Platinum. There are often tax benefits associated with having a LEED certification, and many new government buildings (especially Federal) are required to be LEED certified.

Two points in particular (out of of 100, or so) from the LEED checklist are related to geospatial data. One point is awarded if at least 20% of the building materials (by cost) used in construction were manufactured within 500 miles of the job site. A second point is awarded if 10% of the raw materials of those building materials were extracted, harvested, or recovered within 500 miles of the job site.

As a window glass manufacturer, Tempuri Glass is often asked to provide data about its products that are being considered for use in construction. Tempuri Glass may have a certain advantage over its competitors if it can quickly show that its products would count towards these two points for any arbitrary job site.


Tempuri is a simple organization, making only a single type of product (Soda Lime glass) that is then cut into different sizes per order. Therefore, regardless of how many different sized glass panes are produced by a given facility, the ingredients for that glass is the same. The formulas used will be different between facilities, though, since the raw ingredients will be sourced from different locations, and adjustments may need to be made to the ratios due to environmental factors (things like: elevation, temperature, humidity, etc).

So, for our data model, we just need to know where each facility is, and then the formula used to make the glass at that facility (including the ingredients of that formula and the location where they were harvested from).


Within the data store, the [Geocode] columns of the Facility and FormulaComponent tables use the SQL Server geography type. This is useful for the large-scale/real-world distance calculations that Tempuri Glass needs to perform, since the way that you calculate distance on an sphere or ellipsoid (like the Earth) is vastly different than on a flat map.

In the Entity Framework model (using the June 2011 CTP), the SQL Server geography types are mapped as the new System.Data.Spatial.DbGeography type. This makes the geospatial data a first class citizen of our data model, and not just a castable opaque BLOB, as was the case in the past.

Geospatial data can take on many forms, including Points, Line Strings, Polygons, and collections of these shapes. Even though it’s not apparent from the data model, our [Geocode] data will contain only Points (i.e., a single Latitude/Longitude pair). Likewise, a job site will be specified as a single Point, though there is no hard requirement for this because distance can still be calculated between a Polygon and a Point with no coding change required.

Facility Sample Data







Greenfield, IA



POINT (-94.4547843933106 41.3151755156904)


Spring Green, WI

Spring Green


POINT (-90.053981 43.17431)


Tomah, WI



POINT (-90.477058 43.989319)


Fremont, IN



POINT (-84.9314403533936 41.7186070559443)


Fargo, ND



POINT (-96.8667125701904 46.8985894795683)


Waxahachie, TX



POINT (-96.8427014350891 32.4424403136322)


Hood River, OR

Hood River


POINT (-121.51526927948 45.630620334868)


Vinton, VA



POINT (-79.863876 37.263329)


Casa Grande, AZ

Casa Grande


POINT (-111.78155422210693 32.882073958767954)


Mountain Top, PA

Mountain Top


POINT (-75.896477 41.141327)


Winlock, WA



POINT (-122.926218509674 46.5449155194259)


Durant, OK



POINT (-96.4133548736572 34.0001619910696)


Mooresville, NC



POINT (-80.7865476608277 35.6316281732984)


FormulaComponent Sample Data









Genola, UT

POINT (-111.808204650879 40.0098667779887)


Silica Sand


Houck, AZ

POINT (-109.241695404053 35.2062151838369)


Soda Ash


Trona, CA

POINT (-117.311668395996 35.6955040738332)




Genola, UT

POINT (-111.808204650879 40.0098667779887)


Silica Sand


Houck, AZ

POINT (-109.241695404053 35.2062151838369)


Soda Ash


Trona, CA

POINT (-117.311668395996 35.6955040738332)




Chicago, IL

POINT (-87.6176834106445 41.5738476278005)


Silica Sand


Overton, NV

POINT (-114.4313621521 36.5146030619859)


Soda Ash


Green River, WY

POINT (-109.448783397675 41.5090754257687)


Spatial Querying Algorithm

Input: Job Site Latitude/Longitude


A. Query for closest facility to Job Site within 500 miles:

  1. Calculate the distance between the job site and each facility.
  2. Filter the list of facilities to just those where distance < 500 miles.
  3. Order the list of facilities by distance in ascending order.
  4. The first element (if any) will be the closest facility, and also signifies that the product qualifies as being manufactured within 500 miles

B. If there is a facility within 500 miles, then sum the percentage of formula components that were sourced from within 500 miles of the Job Site:

  1. Calculate the distance between the job site and each of the facility’s formula components
  2. Filter the list of formula components to just those where distance < 500 miles
  3. Sum the Percentages

Output: Boolean of whether the product qualifies; Percentage of the product’s ingredients that qualifies.


Before we can calculate distance using an instance method of the DbGeography type, we need to actually create an instance to represent the Job Site. DbGeography is immutable and does not have a constructor, so instead, a static method must be called to create a new object. There are a number of these factory methods available to create specific kinds of shapes (Point, Line String, Polygon, etc) given different kinds of input (text, byte arrays).

For simplicity, let’s use the .Parse() method, which accepts Well-Known Text (WKT) as input, and assumes a Spatial Reference ID of 4326 (the same coordinate system that GPS and internet mapping sites use).

Note: WKT uses a (Longitude, Latitude) ordering for points, which adheres to the same concept as (X, Y) ordering for Cartesian coordinates.

private static DbGeography CreatePoint(double latitude, double longitude)
return DbGeography.Parse(String.Format("POINT({1} {0})", latitude, longitude));

The first spatial query, written as a LINQ expression, finds the closest qualifying facility. Since SRID 4326 uses meters as the unit of measure, we need to convert 500 miles into meters within the predicate:

private Facility GetNearestFacilityToJobsite(DbGeography jobsite)
    var q1 = from f in context.Facilities
    let distance = f.Geocode.Distance(jobsite)
    where distance < 500 * 1609.344
    orderby distance
    select f;

return q1.FirstOrDefault();

Assuming that a facility was returned, a second LINQ expression can be used to find the sum of Percentage from qualifying Formula Components:

private decimal SumQualifyingPercentages(Facility nearestFacility, DbGeography jobsite)
var q2 = from fc in nearestFacility.Formula.FormulaComponents
where fc.Geocode.Distance(jobsite) < 500 * 1609.344
select fc;

return q2.Sum(c => c.Percentage.GetValueOrDefault(0));

Finally, putting all of the parts together (using a Tuple<> for the output):

private Tuple<bool, decimal> GetResults(double latitude, double longitude)
DbGeography jobsite = CreatePoint(latitude, longitude);
Facility nearestFacility = GetNearestFacilityToJobsite(jobsite);

if (nearestFacility != null)
return new Tuple<bool,decimal>(true, SumQualifyingPercentages(nearestFacility, jobsite));

return new Tuple<bool, decimal>(false, 0);

private void PerformQuery()
double latitude = 47.63752;
double longitude = -122.13343;

var results = GetResults(latitude, longitude);

Entity Framework Spatial: DbGeography and DbGeometry Members

DbGeography Static Property Return Type DbGeometry Static Property Return Type
DbGeography.DefaultSrid int DbGeometry.DefaultSrid int
DbGeography Static Method Return Type DbGeometry Static Method Return Type
DbGeography.FromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.FromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.FromGml(string geographyMarkup, int srid) DbGeography DbGeometry.FromGml(string geometryMarkup, int srid) DbGeometry
DbGeography.FromText(string geographyText, int srid) DbGeography DbGeometry.FromText(string geometryText, int srid) DbGeometry
DbGeography.GeographyCollectionFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.GeometryCollectionFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.GeographyCollectionFromText(string geographyText, int srid) DbGeography DbGeometry.GeometryCollectionFromText(string geometryText, int srid) DbGeometry
DbGeography.LineFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.LineFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.LineFromText(string geographyText, int srid) DbGeography DbGeometry.LineFromText(string geometryText, int srid) DbGeometry
DbGeography.MultilineFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.MultilineFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.MultilineFromText(string geographyText, int srid) DbGeography DbGeometry.MultilineFromText(string geometryText, int srid) DbGeometry
DbGeography.MultipointFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.MultipointFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.MultipointFromText(string geographyText, int srid) DbGeography DbGeometry.MultipointFromText(string geometryText, int srid) DbGeometry
DbGeography.MultipolygonFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.MultipolygonFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.MultipolygonFromText(string geographyText, int srid) DbGeography DbGeometry.MultipolygonFromText(string geometryText, int srid) DbGeometry
DbGeography.Parse(string geographyText) DbGeography DbGeometry.Parse(string geometryText) DbGeometry
DbGeography.PointFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.PointFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.PointFromText(string geographyText, int srid) DbGeography DbGeometry.PointFromText(string geometryText, int srid) DbGeometry
DbGeography.PolygonFromBinary(byte[] geographyBinary, int srid) DbGeography DbGeometry.PolygonFromBinary(byte[] geometryBinary, int srid) DbGeometry
DbGeography.PolygonFromText(string geographyText, int srid) DbGeography DbGeometry.PolygonFromText(string geometryText, int srid) DbGeometry
DbGeography Instance Property Return Type DbGeometry Instance Property Return Type
g.Area double? g.Area double?
    g.Boundary DbGeometry
    g.Centroid DbGeometry
    g.ConvexHull DbGeometry
g.Dimension int g.Dimension int
g.EndPoint DbGeography g.EndPoint DbGeometry
    g.Envelope DbGeometry
    g.ExteriorRing DbGeometry
g.GeometryType string g.GeometryType  
g.IsClosed bool? g.IsClosed bool?
g.IsEmpty bool g.IsEmpty bool
    g.IsRing bool?
    g.IsSimple bool
    g.IsValid bool
g.Latitude double?    
g.Length double? g.Length double?
g.Longitude double?    
g.M double? g.M double?
g.NumGeometries double? g.NumGeometries int?
    g.NumInteriorRing int?
g.NumPoints int? g.NumPoints int?
    g.PointOnSurface DbGeometry
g.ProviderValue object g.ProviderValue object
g.Srid int g.Srid int
g.StartPoint DbGeography g.StartPoint DbGeometry
g.WellKnownValue WellKnownValue DbGeographyWellKnownValue g.WellKnownValue DbGeometryWellKnownValue
g.WellKnownValue.Srid int g.WellKnownValue.Srid int
g.WellKnownValue.WellKnownBinary byte[] g.WellKnownValue.WellKnownBinary byte[]
g.WellKnownValue.WellKnownText string g.WellKnownValue.WellKnownText string
    g.X double?
    g.Y double?
g.Z double? g.Z double?
DbGeography Instance Method Return Type DbGeometry Instance Method Return Type
g.AsBinary() byte[] g.AsBinary() byte[]
g.AsGml() string g.AsGml() string
g.AsText() string g.AsText() string
g.Buffer(double distance) DbGeography g.Buffer(double distance) DbGeometry
    g.Contains(DbGeometry other) bool
    g.Crosses(DbGeometry other) bool
g.Difference(DbGeography other) DbGeography g.Difference(DbGeometry other) DbGeometry
g.Disjoint(DbGeography other) bool g.Disjoint(DbGeometry other) bool
g.Distance(DbGeography other) double g.DistanceDbGeometry other) double
g.GeometryN(int index) DbGeography DbGeography g.GeometryN(int index) DbGeometry
    g.InteriorRingN(int index) DbGeometry
g.Intersection(DbGeography other) DbGeography g.Intersection(DbGeometry other) DbGeometry
g.Intersects(DbGeography other) bool g.Intersects(DbGeometry other) bool
    g.Overlaps(DbGeometry other) bool
g.PointN(int index) DbGeography g.PointN(int index) DbGeometry
    g.Relate(DbGeometry other, string matrix) bool
g.SpatialEquals(DbGeography other) bool g.SpatialEquals(DbGeometry other) bool
g.SymmetricDifference(DbGeography other) DbGeography g.SymmetricDifference(DbGeometry other) DbGeometry
    g.Touches(DbGeometry other) bool
g.Union(DbGeography other) DbGeography g.Union(DbGeometry other) DbGeometry
    g.Within(DbGeometry other) bool