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
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
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.
2. In VS 2022, Blazor WebAssembly App project, you can check the ASP.NET Core hosted or not, what's the difference?
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:
But you can customize it to something like this:
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)
The fake root's web.config is very standardized, no customized info here.
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 ).
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.
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!
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.