{"id":13430652,"url":"https://github.com/alexyakunin/BoardGames","last_synced_at":"2025-03-16T06:30:45.804Z","repository":{"id":53772543,"uuid":"336114881","full_name":"alexyakunin/BoardGames","owner":"alexyakunin","description":"New Stl.Fusion sample and a fully functional web app allowing you to play real-time multiplayer board games. Powered by Stl.Fusion, Blazor, and .NET 5.","archived":false,"fork":false,"pushed_at":"2022-09-09T06:45:07.000Z","size":520,"stargazers_count":71,"open_issues_count":2,"forks_count":8,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-10-23T13:38:49.555Z","etag":null,"topics":["blazor-server","blazor-wasm-mode","board-games","game","game-development","game-engine","real-time","signalr","wasm","webassembly","webassembly-demo"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexyakunin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-04T23:57:17.000Z","updated_at":"2024-09-29T04:12:33.000Z","dependencies_parsed_at":"2022-09-19T01:10:33.755Z","dependency_job_id":null,"html_url":"https://github.com/alexyakunin/BoardGames","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexyakunin%2FBoardGames","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexyakunin%2FBoardGames/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexyakunin%2FBoardGames/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexyakunin%2FBoardGames/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexyakunin","download_url":"https://codeload.github.com/alexyakunin/BoardGames/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221656317,"owners_count":16858741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor-server","blazor-wasm-mode","board-games","game","game-development","game-engine","real-time","signalr","wasm","webassembly","webassembly-demo"],"created_at":"2024-07-31T02:00:56.248Z","updated_at":"2024-10-27T09:30:26.482Z","avatar_url":"https://github.com/alexyakunin.png","language":"C#","funding_links":[],"categories":["Sample Projects"],"sub_categories":["Games"],"readme":"# BoardGames\n\n\"Board Games\" is a [Fusion] sample and a fully functional \nweb app allowing you to play real-time multiplayer board games.\n\n**Note:** this repository wasn't updated for a while, so it uses \nan outdated version of Fusion (v1.3.x, while the current one is v3.7.x). \nNevertheless it's still a good example you can play with \nto learn Fusion. The APIs change, but concepts stay the same :)\n\n\u003cimg src=\"https://img.shields.io/badge/-Live!-green\" valign=\"middle\"\u003e Live version of this app: https://boardgames.alexyakunin.com/\n\nA short video explaining what's unique there:\n\n[\u003cimg src=\"doc/img/BoardGames.jpg\"\u003e](https://www.youtube.com/watch?v=R1XB8UKJ1dk)\n\nThe sample implements a number of features that are \nhard to implement without Fusion. In particular, you might notice\nthat real-time state sync works literally everywhere in it. \nTry opening the sample in two different browsers, sign in using \ndifferent user accounts, and:\n- Create and play a game in both windows\n- Check out what happens with game lists when you're\n  creating a game, making moves, or posting a chat message\n- Try renaming your user \u0026 see its name changes everywhere - \n  even in chat mentions!\n  \n### What's implemented in Board Games\n\n- Two games. I plan to add a couple more  a bit later - \n  there is a common base API allowing to add new games \n  pretty quickly\n- Game lobby, where you can track the state of games you\n  participate in, browse open games created by other users \n  and join them\n- Game chat, which supports mentions. In reality, there is\n  an extendable message parser and modular renderer that \n  supports user and game mentions.\n- User online/offline status tracking. Notice that every \n  user badge displays it.\n- User profile page, where you can edit your user name, add \n  MS/GitHub accounts, see all browser sessions, \"kick\" some\n  of them or sign out from all of them.\n- Full state persistence to any DB supported by EF Core\n- Web API - it's used when the sample works in Blazor \n  WASM mode, so whatever UI can do is available there too.\n\nFinally, the sample supports *both* Blazor Server and \nBlazor WebAssembly modes.\n\nThe [live version] of this app is hosted on Google Cloud GKE:\n- The deployment runs 3 replicas of this service on a small\n  Kubernetes cluster that includes 3 preemptive\n  [e2-small](https://cloud.google.com/compute/vm-instance-pricing#e2_sharedcore_machine_types) \n  nodes ($3.67/mo each)\n- Cloud PostgreSql stores the data; it also runs on\n  the cheapest 1 core/3.75GB RAM host.\n- Both Blazor Server and Fusion require session affinity. \n  It's achieved here with \n  [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/examples/affinity/cookie/)\n  configured to route requests to the same backend host\n  (selected using consistent hashing) relying on `_ngsa` cookie\n- Try opening https://boardgames.alexyakunin.com/api/hostInfo/getHostName\n  normally and without this cookie (e.g. in incognito mode) to see \n  how it works. \n- Check out [deployment.yml](deployment.yml), [service.yml](service.yml),\n  [ingress.yml](ingress.yml), and [.github/workflows/gke.yml](.github/workflows/gke.yml), \n  if you're interested how to configure this.\n                   \n### Ok, real-time. But seriously, what's so new there?\n\nThe implementation cost of real-time updates. Everything you \nsee there required me to write [just 35 extra lines of code](https://github.com/alexyakunin/BoardGames/search?q=IsInvalidating)!\n\n- First 3 `if` blocks have ~ 15 lines of code inside\n- The last one (in `GameService.cs`, the invalidation logic is outside of \n  an `if` clause there) has ~ 20 more.\n  \nAnd if you look at everything else, it's absolutely usual code you'd \nhave otherwise too.\n\n\u003e More precisely, you'd need at least this \"everything else\" to implement \na *non-real-time* version of the same sample that supports just \nBlazor Server.\n\u003e\n\u003e WASM version would require way more - the approach used in this sample,\nwhere server-side services are replaced by their client-side caching\nreplicas (so-called \n[\"Replica Services\"](https://github.com/servicetitan/Stl.Fusion.Samples/blob/master/docs/tutorial/Part04.md)\nin Fusion terms) simply won't work without Fusion-style distributed\nversion of \"computed observable\" that eliminates every RPC call known \nto return the same result as the locally cached one. \n\u003e\n\u003e In other words, if you use Fusion, Blazor WASM mode has virtually \nzero implementation cost as well. \n\n**And this is what allowed me build Board Games single-handedly\nin 9 days.** Proof: \n[the very first commit](https://github.com/servicetitan/Stl.Fusion.Samples/commit/546ae7597bc7fa3a0b3c7f3b84e3a463bc3fd28f)\ncloning Fusion's Blazorise template was made on Feb 1, \nand [I wrote this README describing what's already done](https://github.com/alexyakunin/BoardGames/commit/b1042a74209050cb79fb4e248f84a03c2b600fbf)\non Feb 10 (though at that point there was just one game). \n\n### Looks interesting, how do I learn more about Fusion?\n\nCheck out [Fusion] and its \n[other samples](https://github.com/servicetitan/Stl.Fusion.Samples);\njoin our [Discord Server] to ask questions.\n\nP.S. I am sure there are some bugs - if you'll find one, \nplease \n[report an issue](https://github.com/alexyakunin/BoardGames/issues)!\n\n[Fusion]: https://github.com/servicetitan/Stl.Fusion\n[Live version]: https://boardgames.alexyakunin.com/\n[Discord Server]: https://discord.gg/EKEwv6d\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexyakunin%2FBoardGames","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexyakunin%2FBoardGames","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexyakunin%2FBoardGames/lists"}