We create unique software tools to help stock traders and investors


Explain a few basics on Microsoft Blazor via a full-blown web browser game

 Have you played "PLATO'S DISCIPLE ON WALL STREET", our web game simulating stock day trading? (In case you haven't, here is the link https://AristotleIsNotAlwaysRight.com/game)

It's mostly done in Microsoft Blazor, which takes advantage of an important capability of Blazor: once loaded, the browser game can totally run within its client browsing session, no server hosting actually needed after that point. Technically speaking, once user starts playing the browser game, even with the Internet broken situation, the gamer can still play without any disruption. (Given that this web game is solo game, not multi-player game)

A little background

Since HTML5, the browser technology evolved very fast, now to a whole new level of capabilities! To trigger those capabilities, The almighty beloved JavaScript is still the de facto king. Even though all modern browsers are optimized to execute JS very fast, it's quite cumbersome to maintain large scale of complex code in script, especially when dealing with 2D/3D drawing or real-time communications. That's what WebAssembly, WASM comes out for. WASM is industry standard now. It allows the browser to host and execute binary code (similar to DLL/EXE level of code). Real time communications, 2D/3D drawings can be done in compiled code within browser. (Binary code, the "assembly", is downloaded to client browser session's cache during the client's first http GET action). You can build WASM in C/C++ or C#, as long as the code compiles to WASM. Microsoft's WASM technology is called Blazor.

Because of IP and NDA restrictions, We can't share code of this game. But I'd like to share some tricks & tips to explain some common myths about Blazor technology. Hopefully this can at least make things a bit easier when you need to deal with Blazor down the road.

Points of interest

1. Downloading size in client's browser

When gamer first access the game from URL, #1 thing happens to the browser is "loading". Under the hood of this "loading", Microsoft version of WebAssembly libraries is downloaded to client browser session. These libs serve as "runtime" of your real customized compiled binary code. this "runtime" will serve as a mini-OS within browser session, to execute the binary code. It will also serve as bridge/translator, exchange command orders between your binary code and almighty JavaScript (yes, blazor/WASM still using JavaScript to do DOM operations under the hood, as a Blazor programmer, you still need to know how to interact with JavaScript in your C# code, but that's another story). 

Admitted, the first downloading is not small. From 10-15MB, depending on the client browser, and the client computer OS. This is just one time job. Which means that, if the gamer never cleans his/her browser cache, these libs will sit there (browser's cache) for a long time. and next time (even days after) when gamer uses the same browser to open the same URL, the only thing to be downloaded is just pure game data, which are just around 500KB - 800KB. 

To track the client downloading size, open your Chrome browser, hit F12 to go to DevTools. Open the "Network" tab, by clicking "Disable cache" and hit browser's reload button, you can see that 10-15MB size of downloading. Usually this is what gamer's first URL access going to get. Then enable the cache (by clicking "Disable cache" again), you can see consistently 500KB to 800KB size of downloading (after the first downloading), every time you test it.

Graphical user interface, application

Description automatically generated


2. In VS 2022, Blazor WebAssembly App project, you can check the ASP.NET Core hosted or not, what's the difference?

A screenshot of a computer

Description automatically generated with medium confidence

Blazor WebAssembly always starts at an entry point which is Index.html. So if you want your deployed web app does something before index.html got hit, this "hosted" check could be your friend. In our case, we don't need this "hosted" option. So technically speaking, our Blazor project is a "stand-alone" project, which means, if it's deployed to IIS web server, it can totally serve its own URL (which by default starts at index.html). Even so, we still made a choice, which was to deploy the Blazor game under another web app, although this web app has nothing to do with the Blazor game (other than a link). So to speaking, the main URL in our case is https://AristotleIsNotAlwaysRight.com and the game's URL is https://AristotleIsNotAlwaysRight.com/game. The game URL can be directly hit, it doesn't necessarily need a "parent". The reason for this "parent" is a business decision, not a technical one. I point it out is to let you know that, there are subtle choices here.

3. How to customize the "ugly" loading screen

If you don't do anything, the Index.html mentioned above still does its work, which is asynchronously loading the WASM libraries and game's compiled binary code. It just does it in an "ugly" screen, like this: 

Graphical user interface, text, application

Description automatically generated

But you can customize it to something like this:

Graphical user interface

Description automatically generated with medium confidence

There are many sample code on how to do this. Just google "how to customize Blazor index.html".

4. Tricks on physical path of the deployment

Even though it sits under a "parent" ASP.NET web application, our Blazor game is still a stand-alone app. It means that anyone can directly go there, without hitting the parent web and without triggering any other server side code before the index.html runs. 

As you can see, a IIS deployed stand-alone blazor web app's physical file path root is very simple. But this root is a fake root, the real binding in IIS is under its wwwroot (I'll show you later). However, you have to do it this way. Let's say, for example, the whole physical folder for the fake root is like this D:\ABC\ (wwwroot folder & web.config)


Description automatically generated with medium confidence

The fake root's web.config is very standardized, no customized info here.


Description automatically generated

Under the wwwroot path, it's another story. Below is the screenshot of wwwroot structure. (sorry I have to cross out two business related entries). You can see the web.config under this folder is also very "standardized", nothing fancy in this web.config either. The compiled game code DLL is in _framework folder. All Microsoft WASM libs are also there (10-15MB downloading also happening here ).

Graphical user interface, text

Description automatically generated

The most important "customized" config is actually in "index.html"

Here is the snippet of index.html. The yellow marked piece matters A LOT.

If this is totally a "stand-alone" web app without any parent, you should use the above line <base href="/" /> which is commented out now. Because we made this blazor app sitting under a parent app, so you need this "./" thingy. If you have more levels up or down, you have to play with this dot thing, just test it until you get the right loading screen. Bonus trick: The best way to debug this dot thing (or the proper path), is to use Chrome/Edge's F12 DevTools, to modify the sources while loading the screen, until you see no errors.


Description automatically generated

5. How it looks in IIS web server  

So as you can see, the game is deployed as a web app under another parent app, but it still its own app. And make sure that, even though the fake root (as mentioned at the beginning of #4, as D:\ABC\) is out there, the real "Physical Path" in IIS setup has to point to D:\ABC\wwwroot. This is very important!

Graphical user interface, text, application

Description automatically generated


6. Client Browser Matters

Although WebAssembly, WASM, is already an industry standard, it's up to browser vendors how to implement it. Different vendors might have different implementations. Our web game works well in PC/Mac's Chrome/Edge browsers, but not on mobiles and not on Apple Safaris Browser (nor Firefox). So you have to test your own pilot Blazor projects to target your clients.


Hopefully these basics can help a bit when you need to deal with Blazor later.