"Board Games" is a Fusion sample and a fully functional web app allowing you to play real-time multiplayer board games.
Note: this repository wasn't updated for a while, so it uses an outdated version of Fusion (v1.3.x, while the current one is v3.7.x). Nevertheless it's still a good example you can play with to learn Fusion. The APIs change, but concepts stay the same :)
Live version of this app: https://boardgames.alexyakunin.com/
A short video explaining what's unique there:
The sample implements a number of features that are hard to implement without Fusion. In particular, you might notice that real-time state sync works literally everywhere in it. Try opening the sample in two different browsers, sign in using different user accounts, and:
- Create and play a game in both windows
- Check out what happens with game lists when you're creating a game, making moves, or posting a chat message
- Try renaming your user & see its name changes everywhere - even in chat mentions!
- Two games. I plan to add a couple more a bit later - there is a common base API allowing to add new games pretty quickly
- Game lobby, where you can track the state of games you participate in, browse open games created by other users and join them
- Game chat, which supports mentions. In reality, there is an extendable message parser and modular renderer that supports user and game mentions.
- User online/offline status tracking. Notice that every user badge displays it.
- User profile page, where you can edit your user name, add MS/GitHub accounts, see all browser sessions, "kick" some of them or sign out from all of them.
- Full state persistence to any DB supported by EF Core
- Web API - it's used when the sample works in Blazor WASM mode, so whatever UI can do is available there too.
Finally, the sample supports both Blazor Server and Blazor WebAssembly modes.
The live version of this app is hosted on Google Cloud GKE:
- The deployment runs 3 replicas of this service on a small Kubernetes cluster that includes 3 preemptive e2-small nodes ($3.67/mo each)
- Cloud PostgreSql stores the data; it also runs on the cheapest 1 core/3.75GB RAM host.
- Both Blazor Server and Fusion require session affinity.
It's achieved here with
NGINX Ingress Controller
configured to route requests to the same backend host
(selected using consistent hashing) relying on
_ngsa
cookie - Try opening https://boardgames.alexyakunin.com/api/hostInfo/getHostName normally and without this cookie (e.g. in incognito mode) to see how it works.
- Check out deployment.yml, service.yml, ingress.yml, and .github/workflows/gke.yml, if you're interested how to configure this.
The implementation cost of real-time updates. Everything you see there required me to write just 35 extra lines of code!
- First 3
if
blocks have ~ 15 lines of code inside - The last one (in
GameService.cs
, the invalidation logic is outside of anif
clause there) has ~ 20 more.
And if you look at everything else, it's absolutely usual code you'd have otherwise too.
More precisely, you'd need at least this "everything else" to implement a non-real-time version of the same sample that supports just Blazor Server.
WASM version would require way more - the approach used in this sample, where server-side services are replaced by their client-side caching replicas (so-called "Replica Services" in Fusion terms) simply won't work without Fusion-style distributed version of "computed observable" that eliminates every RPC call known to return the same result as the locally cached one.
In other words, if you use Fusion, Blazor WASM mode has virtually zero implementation cost as well.
And this is what allowed me build Board Games single-handedly in 9 days. Proof: the very first commit cloning Fusion's Blazorise template was made on Feb 1, and I wrote this README describing what's already done on Feb 10 (though at that point there was just one game).
Check out Fusion and its other samples; join our Discord Server to ask questions.
P.S. I am sure there are some bugs - if you'll find one, please report an issue!