Press "Enter" to skip to content

Build a C#/WPF RPG

This is a new WPF/XAML game, based on the game from my Windows Form tutorial: Learn C# by Building a Simple RPG


For the latest version of the complete solution, visit:



Lesson 00.1: Overview



Lesson 01.1: Installing Visual Studio Community 2015 – Update 3

Lesson 01.2: Installing TortoiseSVN and VisualSVN



Lesson 02.1: Planning the Game



Lesson 03.1: Creating the Solution and Game Screen

Lesson 03.2: Creating and Using a Subversion Repository

Lesson 03.3: Creating the Player Class

Lesson 03.4: Creating the GameSession (ViewModel) Class

Lesson 03.5: Displaying the Player Object

Lesson 03.6: Update Player data with the PropertyChanged event

Lesson 04.1: Creating the Location class

Lesson 04.2: Creating the World

Lesson 04.3: Moving in the game world

Lesson 04.4: Improving the World – Inheritance and INotifyPropertyChanged

Lesson 04.5: Improving the World – Factory and Guard Clauses

Lesson 05.1: Creating the Game Item Factory

Lesson 05.2: Creating the Player Inventory

Lesson 06.1: Creating the Quest Factory

Lesson 06.2: Using Quests in the Game

Lesson 07.1: Creating Monsters

Lesson 07.2: Adding Monsters to Locations

Lesson 07.3: Sending Messages from the ViewModel to the View

Lesson 07.4: Monster Combat

Lesson 07.5: Monster and Combat Refactoring

Lesson 08.1: Completing Quests

Lesson 09.1: Creating Traders

Lesson 09.2: Adding the Trade Screen


Cleanup/refactoring, before adding more features

Lesson 10.1: Refactoring Base Class for Player, Monster, and Trader

Lesson 10.2: Grouping GameItems in Inventories

Lesson 10.3: Refactoring – Encapsulating LivingEntity Properties (Hit Points and Gold)

Lesson 10.4: Bug Fix – Removing multiple items from GroupedInventory

Lesson 10.5: Encapsulating Level and ExperiencePoints Properties

Lesson 10.6: Clean up property setters and PropertyChanged notifications


Create a base for automated tests

Lesson 11.1: Creating the Unit Test Project


New game features

Lesson 12.1: Making the GameItem class more flexible

Lesson 12.2: Creating the AttackWithWeapon command

Lesson 12.3: Making the Action class more flexible with an interface

Lesson 12.4: Letting the Monster use AttackWithWeapon

Lesson 12.5: Creating the first consumable GameItem

Lesson 12.6: Refactoring after adding Actions

Lesson 12.7: Creating recipes

Lesson 12.8: Crafting items with recipes

Lesson 13.1: Add keyboard input for actions, using delegates

Lesson 13.2: More keyboard actions (and fixes)


Load game world objects from XML files

Lesson 14.1: Moving game data to external files

Lesson 14.2: Creating extension methods

Lesson 14.3: Read World (Location) data from an XML file

Lesson 14.4: Read Monster data from an XML file

Lesson 14.5: Move Remaining Game Data to XML Files



Lesson 15.1: Bug Fixes, Unit Tests, and Tooltips

Lesson 15.2: Catch and log exceptions

Lesson 15.3: Building a “functional” inventory class

Lesson 15.4: Using GitHub to upload and download a solution


Better combat

Lesson 16.1: Adding centralized messaging

Lesson 16.2: Creating the Battle class

Lesson 16.3: Complex attack initiative and hit success logic


Continued lessons

Lesson 17.1: Saving and loading game state

Lesson 17.2: Reducing serialized data in save game file

Lesson 17.3: Add a menu to save and load the game state

Lesson 17.4: Automated test for saved game reader


Cleanup/bug fix

Lesson 99.1: Fix event subscriptions

Lesson 99.2: Replace random number library


Customizable Player attributes

Lesson 18.1: Making Configurable GameDetails

Lesson 18.2: New starting windows and configurable player races

Lesson 18.3: Player creation screen

Lesson 18.4: Adding Player Attributes to Living Entities

Lesson 18.5: Update game loading and saving



  1. Michael
    Michael February 19, 2021

    Hi Scott, i liked your old version and I like this version of your tutorial. Something I picked up on when I downloaded the code. Your save game doesn’t work. instead of loading my data, it loads Scott, Fighter, and 1 million gold. Also puts items in inventory I didnt have when I saved it, Instead it puts the default in. Sorry to disturb you.

    • Scott Lilly
      Scott Lilly February 19, 2021

      Hi Michael,

      Did you recently get the complete solution from GitHub? If so, there might be a problem. I’m currently changing the Player class, and the changes might break the load/save game functions (they’re definitely broken on the changes I’m about to post).

      • Michael
        Michael February 20, 2021

        yes I did, also checked from lessons and same problem.

        • Scott Lilly
          Scott Lilly February 20, 2021

          I should be putting out the next lesson tomorrow (Sunday). The changes add PlayerAttributes to the Player object, but breaks the save/load game – since the Player object is a new format. The next lesson will be a rewrite of the save/load game. I’ll make sure the new save/load game changes work with the new format.

  2. Ryan
    Ryan March 12, 2021

    Hello Scott, great work, I really like the layout and capabilities of your game engine! So I took it upon myself to convert it into a console game! So far it has gone pretty smoothly and I am currently working on bringing in all the functionality and trying to keep control flow to matching the WPF as much as possible. Thank you for doing these tutorials and coding in such a clean manner that it can be reused without a GUI!

    • Scott Lilly
      Scott Lilly March 12, 2021

      You’re welcome, Ryan! It’s great to hear you were able to convert the game to a console app. This type of architecture is something I try to do in corporate programs – which need to be supported and modified for many years.

  3. Al
    Al March 13, 2021

    Hi Scott. Really loving these tutorials so far, so thank you!

    I’m not sure if this has been asked before but it would be really useful to see how you can add dialog options to NPCs and get quests from them by talking to them.

    • Scott Lilly
      Scott Lilly March 14, 2021

      You’re welcome, Al!

      Yes, several people have asked for NPC conversations to get quests, so it’s on the list of future enhancements. That will probably be combined with progressive quests (you have to complete the NPC’s first quest before you can get their 2nd quest) and maybe your level of friendliness with the NPC’s faction.

  4. Stéphane
    Stéphane March 15, 2021

    Bonjour Scott,
    I just finished your lessons and it took me a good twenty hours from first to number 18.5.
    This set of lessons is as addicting as a good novel whose original idea is excellent.
    Passionate about CSharp and Fighting Fantasy, I can confirm the learning goal has been reached and that it worked well.
    I will keep what I just learned in mind, and I will no doubt thank you for it later.
    I am particularly grateful to you and also to the support in help comments.

    • Scott Lilly
      Scott Lilly March 15, 2021

      Thank you, Stéphane!

      I’m glad to hear you enjoyed the course and learned some programming. For people who enjoy learning, programming can be a great hobby or career.

      Good luck with your programming future!

  5. Ryan
    Ryan March 16, 2021

    Hello, again Scott! I love your enthusiasm and passion!!

    Also on the comment about adding NPC dialog, although I have not used it directly another project uses Ink in C# to allow interactive dialog definition and compilation, making for a rich experience, I imagine it can be applied to various architectures (console WPF, Forms, Web).

    For me, I am using Goblin Factory Konsole to break up my console window into regions, and populating it directly and indirectly via changes to properties. The initial write is done directly by calling ExcuteLineUpdates() on the Window with the registered updates, I then registering a PropertyChangeEvent handler that matches property name to UI property name and updates the change when it occurs. I have not figured out how to update the line yet, so I just call the function stored at the key and output the key and the value that was returned to update the window when a change is relevant to that Konsole Window.

    I moved the code to a Gist, because this site would probably mess up the formatting

  6. Jeff J
    Jeff J June 2, 2021

    Glad to see this project is continuing. I had completed a good portion of the other RPG you had. Great tutorial!

    Couple of questions on this one.
    Have you thought about game timing? (using machine state, if that’s the correct terminology) The last tutorial was turn based and battle was very abrupt. No time for a character to react

    What are your thoughts on magic and magic devices (ex. wands have finite charges, can be recharged, but never back to 100%, can a spell miss it’s target based on a players attribute, what about a chance for a spell to be deflected of the target and possibly hit the player……can the player then deflect that spell and hit something random (would be funny in a MUD and have a fireball just ricochet around the room lol) etc etc)

    Do you have plans to expand this to multi-user?


    • Scott Lilly
      Scott Lilly June 2, 2021

      Thanks Jeff,

      I moved into a new apartment last weekend and need to do some work to make my office a little quieter, so I can get back to making new videos.

      I am looking at adding a timer loop to the game and some of the other things you mentioned. You can see a list of the current plans for the game at the project’s wiki and the project’s issue list. If you have any suggestions, please add it as a “Feature Request” on the Issues page.

      There aren’t any current plans to make the game multi-player. It would be nice, but would take a bit of work. I am starting to look to outsource some of my tasks, so I’ll have more time and energy to create new things (instead of editing, cleaning up audio, posting, etc.) And I’m open to contributions to SOSCSRPG code – once it’s converted to .NET 5.

      Take care!

Leave a Reply

Your email address will not be published. Required fields are marked *