Lessons – Simple RPG

Follow along with the Simple RPG tutorials as we learn new areas of .NET and Azure technologies focused around Blazor client applications and Azure Functions for web service backends.

The source code for these lessons can be found in the following repository: https://dev.azure.com/d20Tek/SimpleRPG/_git/simple-rpg-game

Live game site running at: https://bit.ly/simple-rpg-v2.

Links: Chapter 1 | Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6


Chapter 1: Getting Started

This chapter starts the Simple RPG game. We learn all about the prerequisites and tools to get started in Blazor development. While getting set up isn’t always fun, doing this correctly will speed you along your development process.

Lesson 1.1: The Background
Background information about design and technology for lesson series.

Lesson 1.2: The Prerequisites
The tools and subscriptions needed to work with these lessons.

Lesson 1.3: Setting up Azure DevOps
Getting Azure DevOps org, project, and source code repository set up.

Lesson 1.4: Create Initial Blazor Project
Creating the initial game solution and Blazor project via Visual Studio.

Lesson 1.5: Using Blazorise Component Library
How to find and use component libraries in Blazor project using NuGet Package Manager.

Lesson 1.6: Basic Screen Layout
Use Blazorise to author the basic game screen layout – concepts like components and responsive UI.

Lesson 1.7: Adding Unit Test Project
Unit testing is important to software project – setting up a test project for our game.

Lesson 1.8: bUnit to Test Blazor Components
Unit testing is important to software project – setting up a test project for our game.

Lesson 1.9: Azure Build Pipeline
Create an Azure Pipeline to perform an automated build on every source code commit — in all of our branches.

Lesson 1.10: Building Game Splash Screen
Show a fun splash screen while our Blazor application/game loads.

Lesson 1.11: The Wrap
Wrap up the chapter with steps to complete a pull request and get our code to the main branch.


Chapter 2: Simple Game Engine

This chapter starts with a simple set of model classes and game session. These will be the building blocks of the game, and allow us to investigate the concepts of class libraries and the Model-View-ViewModel (MVVM) design pattern for applications/games.

Lesson 2.1: Initial Player Class
Create our game engine class library and our first model class – Player.

Lesson 2.2: Initial GameSession View Model
Define the MVVM pattern with description and links. Then, create our first view model. – GameSession.

Lesson 2.3: Connecting Player – GameSession – Game Screen
Complete our MVVM pattern investigation by implementing the View – Game Screen. Learn about Blazor databinding and event handling.

Lesson 2.4: Testing the MVVM Components
Writing tests for the various layers of MVVM, and learning to register Blazorise services for component tests.

Lesson 2.5: Using Blazor Dependency Injection
Learn about the Dependency Injection design pattern and a real-world use of it in our game.

Lesson 2.6: Refactoring to PlayerComponent
Refactor the game screen to create a Player component. Learn about Blazor components and how to pass parameters to and unit test them.

Lesson 2.7: Adding a Mocking Test Framework
Install and use the Moq framework to implement Mock objects rather than manually building all mock classes.

Lesson 2.8: Game Location
Focus on building a new feature (Game Location) by extending our MVVM design.

Lesson 2.9: Creating the Game World
Building out the Game World with all locations while learning new C# constructs and the Factory Method pattern.

Lesson 2.10: Moving in the Game World
Build new view model class to manage movement operations and a component to display direction buttons.

Lesson 2.11: The Wrap
Wrap up and review of this chapter. Learn how to access commit changes to review the code changes that correspond to a given lesson.


Chapter 3: Game Engine with Items and Combat

In this chapter, we will delve deeper into building our game engine and user interface. We will introduce inventory, traders, and monsters. We will also investigate the creation of a simple combat system.


Lesson 3.1: Game Items and Factory
Create items and weapons for our game – learn about C# inheritance and InternalsVisibleTo attribute.

Lesson 3.2: Initial Player Inventory
Add inventory list to Player and create Blazor component to show the inventory.

Lesson 3.3: Build Inventory System
Build more robust Inventory component and refactor the game engine to use it.

Lesson 3.4: Random Dice Roller
Learn to use a DiceNotation NuGet package to build randomness and variability into your game engine.

Lesson 3.5: Creating Monsters
First step of the simple combat system – create Monster model class and factory.

Lesson 3.6: Adding Monsters to Locations
Add monster to locations in the game world, and create a MonsterComponent to display it in the game screen.

Lesson 3.7: Displaying Game Messages
Define the DisplayMessage class and use it to show useful messages from the game engine to the player.

Lesson 3.8: Simple Monster Combat
Update game engine to allow players to attack monsters at specific locations in the village.

Lesson 3.9: Adding Traders to the Game Engine
Traders allow players to buy and sell items – adding Trader capabilities to the models and view models.

Lesson 3.10: Building Trader Modal Screen
Learn to use the Blazorise Modal component to show a Trader Screen that allows players to buy and sell items.

Lesson 3.11: Adding Quests to Locations
Add the Quest feature to the game engine and game screen.

Lesson 3.12: Completing Quests
Let’s finish the Quest feature by completing the quest and getting our rewards.

Lesson 3.13: The Wrap
Wrap up and review of chapter 3.


Chapter 4: Enhanced Game Engine

In this chapter, we will build more features for game actions, consumable items, recipes and crafting items, complex combat, and loading game data from data files.

Lesson 4.1: Adding Hit Point, Gold, and Level Management
Managing how the Player handles hit points, levels, and gold. Learn about [Theory] attribute for xUnit.

Lesson 4.2: Refactoring to Use Attack Command
Learn about the Command design pattern, build our first Attack command, and refactor the code to use this new action.

Lesson 4.3: Monsters Attack with Weapons
Extending use of the Attack command to handle monster attacks as well… refactoring of the GameSession combat methods.

Lesson 4.4: Create the First Consumable Item
Creating consumable items feature (for healing) all the way from model changes, new command, view model updates, and new presentation element.

Lesson 4.5: Craft Items with Recipes
Crafting new game items is an important part to our game. Let’s see how we can add that capability.

Lesson 4.6: Add Keyboard Shortcuts for Game Operations
Using the keyboard is important in games. We look at directly processing key press events and using HTML accelerator keys.

Lesson 4.7: Ability to Display Quest and Recipe Data
We look at showing game data upon player request to improve our game’s discoverability.

Lesson 4.8: Create A Centralized Message Broker
Learn the Observer design pattern while implementing the DisplayMessageBroker to show display messages from any class.

Lesson 4.9: Enhanced Combat with Battle Class
Refactor combat code from GameSession view model to the Battle class.

Lesson 4.10: Attack Initiative and Hit Logic
Build more complex combat simulation by providing attack initiative (who attacks first) and logic to manage attacks hitting or missing the opponent.

Lesson 4.11: Load Item Data from JSON File
Learn about JSON files and serialization while loading GameItem data from an embedded resource. Also learn about the Data Transfer Object pattern.

Lesson 4.12: Read Monster Data File
Continue learning our serialization patterns by loading monster data from file, and refactoring the LivingEntity model class.

Lesson 4.13: Read World Data from File
Continue learning our serialization patterns moving the world location data to a JSON file too, and refactor the Location model class.

Lesson 4.14: Move Remaining Data to JSON
Wrapping up our adventures in serialization and JSON by moving data for quests, recipes, and traders to files.

Lesson 4.15: The Wrap
Review of the lessons we learned in this chapter and final model classes refactoring.


Chapter 5: Using Azure for Deployment & Services

In this chapter, we will start by deploying our game to Azure so that players can access it from anywhere in the world. We will learn some of the key concepts in Azure Serverless architecture. Then we will build Azure Functions to provide game data via web services to create an online game.

Lesson 5.1: Introduction to Serverless Architecture on Azure
Learn about the new concepts of Serverless architecture and how it can be built with Azure services.

Lesson 5.2: Setting up Azure Storage Account for Static Website
Learn to create a new Azure Storage account and configure it to host static websites, like our SimpleRPG game.

Lesson 5.3: Create Continuous Deployment Pipeline for Blazor App
Learn about continuous delivery and how to use Azure DevOps to deploy our SimpleRPG game to Azure, so that it is accessible to the public.

Lesson 5.4: Create New Azure Functions Project
Create a new Git repository for our services and create the basic Azure Functions Project. Learn how to build, run, and debug an Azure Function.

Lesson 5.5: Create Simple Web Service to Retrieve ItemTemplates
Create our first real Azure Functions service to retrieve ItemTemplates from a JSON resource file. Create a unit test project for Azure Functions code.

Lesson 5.6: Build Repository Pattern for Data Access
Learn about the Repository pattern and how to apply it to loading our embedded resource data file. Learn about querying, filtering, and sorting data from our Repository.

Lesson 5.7: Design REST Service for Data Retrieval
Learn about the RESTful web service architectural design paradigm and use the principles to enrich our ItemTemplateService.

Lesson 5.8: Microservices Concepts With MonsterTemplateService
Learn about the microservices architecture, using the Builder pattern to simplify repository creation, and use those concepts to build the MonsterTemplateService.

Lesson 5.9: Refactor Service Code and Create LocationTemplateService
Refactor duplicate service code into a helper class, refactor existing services to use it, and build the LocationTemplateService with the new pattern.

Lesson 5.10: Complete the Game Services
Complete the remaining services to provide all of our game data.

Lesson 5.11: Create CI Pipeline for Azure Functions Project
Create a continuous integration/build pipeline to build and test our Azure Functions app in all branch commits and pull requests to the main branch.

Lesson 5.12: Create CD pipeline for Azure Functions App
Create a continuous delivery/release pipeline to deploy our Azure Functions app to our Azure subscription and resource. Then learn how to start new releases.

Lesson 5.13: Build Reusable Service Client for Game Engine
Create GameServiceClient in our game engine to encapsulate all of the communication with our services. Create tests to validate all of the GameServiceClient functions.

Lesson 5.14: Use Service Client to Retrieve ItemTemplates From Game Service
Use GameServiceClient in the ItemFactory to load item data from our game services. Update game setup code and tests to load game data from our web services. And learn about CORS.

Lesson 5.15: Retrieve Remaining Game Data from Services
Convert the remaining factories in our game engine to load their data from corresponding game web services.

Lesson 5.16: Redeploy SimpleRPG Game to New Storage Account
Create new storage account with static website hosting for latest version of the game, update release pipeline to deploy to the new storage account, and release the game to Azure.

Lesson 5.17: Upgrade Blazor Project and Dependencies to .NET 5
Upgrade all of our projects to .NET 5, work through required code fixes for breaking changes, and update our dependent packages (Blazorise and bUnit).

Lesson 5.18: The Wrap
Quick review of all the Azure features that we learned about in this chapter.


Chapter 6: Experiment with Azure Storage Services

In this chapter, we will investigate several Azure Storage options and update our game services to work with each. We will see all of these Azure Storage services in use and pick the right one for our game.

Lesson 6.1: Introduction to Azure Storage Options
An introduction to various Azure Storage options with brief descriptions of each. The starting point for storage solutions that we will use in our services.

Lesson 6.2: Create Blob Storage Container
Start investigation of Azure Blob Storage. Learn how to set up a Blob container with our game data JSON files.

Lesson 6.3: Create Blob Storage Repository
Implement new repository that reads data from Azure Blob Storage, surface new blob repositories through our RepositoryFactory, and build initial tests for the repository.

Lesson 6.4: Refactor Services to Consume Multiple Repositories
Refactor our Azure Function Services to use different backend repositories based on the service query string. Refactor the test classes to remove duplicate code and handle test variations for each repository.

Lesson 6.5: Create Azure Tables with Game Data
Learn to set up Azure Table storage in Azure Portal. Learn how to set up a Table and enter data for each of our game data JSON files.

Lesson 6.6: Create Table Storage Repository
Create the TableStorageReadRepository to retrieve game data from our Table Storage account. Build the TableStorageAdapter to isolate storage specific integration code. And a full set of unit tests to validate the new repository.

Lesson 6.7: Surface TableStorageReadRepository to Game Services
Create repository builders for instances of TableStorageReadRepository. Refactored RepositoryFactory to remove duplicate code and support the new TableStorage builders.

Lesson 6.8: Create Game Data in Azure CosmosDb [coming soon…]


Please provide any feedback you have about the tutorial and individual lessons.