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


Customizable Player attributes

Lesson 18.1: Making Configurable GameDetails

Lesson 18.2: New starting windows and configurable player races


Miscellaneous bug fixes

Lesson 99.1: Fix event subscriptions

Lesson 99.2: Replace random number library


180 thoughts on “Build a C#/WPF RPG

    1. Thanks Daniel. I’ve been looking at getting back to creating more lessons, but I think we might need to switch from .NET Framework to .NET Core (since that’s the direction Microsoft is going).

  1. Hello Scott. I was wondering, will I learn C# from scratch if I’ve never programmed before through this course? I found this on Reddit as I was looking for something more practical to learn from

  2. I just wanted to say thank you for providing this WPF lesson. I learned way more by following along in this type of project than hundreds of hours of youtube tutorials. There’s something great about being able to see a whole project come together with a real application and see you refactor and not having everything perfect like in most tutorials. I learned the most by seeing the whole thought process and you do a wonderful job explaining the basics and then slowing introducing advanced concepts.


  3. Just finished the basics on the old tutorial, and am looking forward to adding bells and whistles with your other lessons. I’ve REALLY enjoyed these lessons and appreciate all the time that went into writing and organizing these concepts. 🙂

  4. Hey Scott,

    A few things I was wondering about as the game evolves. Will you eventually be showing us how to create a 2D JRPG style interface for the game? I’m really intrigued by the idea of how the underlying framework and features that you been walking us through might one day be the back end for a graphic video game.

    Also, one feature I would be interested in seeing in a tutorial would be how we might add game pad/joystick support at this stage of the game. A while back I came across some API’s for game controller support. It’s an advanced topic for sure but if we are headed toward a 2D style RPG it might be interesting to see how that’s done. I think I’m gonna try to add that to my game here soon.

    Finally, I’ve been playing around with this idea of a game/world creation feature in my version of the game where the game would have two basic modes of operation. A play or run mode and an edit or design mode. Is there a chance you might tackle that idea later on?

    I’m loving the tutorials and learning so much. In fact I probably spend more time studying your techniques than any other C# blog I’ve come across. Keep them coming if you can!



    1. Hi Gary,

      The plan is to eventually add JRPG-style graphics, although that’s not planned for anytime soon. But, if you had asked me in January what my plans were for 2020, I wouldn’t have said, “Being quarantined in my apartment, discussing some tiger show” 🙂 The big thing is deciding how to add the graphics: hand-written code, MonoGame, Unity, or something else. I haven’t used MonoGame or Unity, so I’d need to learn one of them first.

      I haven’t thought about gamepad/joystick input. But, if you’ve made it to lesson 13.2, where we connect key presses to movement actions, you should be able to add that fairly easily.

      Having a separate WPF application to let you create your own game data XML is in the plans. I just want to get past the item enhancement changes (e.g., adding gems to improve weapons, jewelry, or armor) before creating that app. Otherwise, we double our work. Most changes to the game models would require a related change to the game data building app.

      There is a rough outline of the plans at: If you have an idea to add, please let me know.

      Take care!

      1. Hi Scott,

        This series is A++.
        Just reading your post and your rough outline. Would you be open to folks submitting their own code for trying to finish your TODO list? Kind of like Mini challenges? Could be a branch from main series lineup? Just pondering.

        I tried using Core 3.1 but can’t get the images to display. Not sure if need to import a library sense Microsoft is trying to make it platform independent?


        1. Thanks James!

          I’m definitely open to have other people contribute code. But, I probably need to get a few things prepared first, like continuous builds in GitHub, coding standards, and maybe converting to .NET Core (since that’s the future Microsoft has for C#).

          For the images, have you gotten to lesson 14.1 yet? That’s where we change the way we load images. The new technique might work in .NET Core.

          1. Scott,
            I’m not to 14.1 yet but working to it. Just finished 9.2 and after that lesson my mind started racing to what cool things I could do with that knowledge 🙂

            Is there an easier way to switch or create a branch to do a project in .NET Core, other than having to create a new solution from the start and just copying the cs and XML files?
            From what I read looks like version 5.0 everything converges into one so maybe just wait till then?

            For your TODO maybe add custom controls and or custom icons for the windows?


          2. James,

            I haven’t found an easy/automated way to convert a .NET Framework project to a .NET Code project. It seems like that would be a fairly easily tool to write. You’d need to convert the csproj files to the new format. The problem would be with any NuGet packages, if they didn’t have a .NET Core version. That sounds like a good weekend project (once I finish my other weekend projects).

            I was thinking of doing the switch when .NET 5.0 is released (or maybe when the pre-release versions start to become available). It’s probably about time to start creating a roadmap for that and having other people contribute code changes.

  5. I have to say, This has been amazing. Thank you for all this.
    I have made significant changes to mine to both push myself and to learn on my own.
    I have not touched the actual game code yet/much, mostly because I want to keep adding as you add, and it is much easier if my code mostly follows yours.
    Some things I have added I’ll list below.(many going off tricks and lessons you have previously provided)
    Mostly because many of my Additions are useful, and help expand the “game” element of the game and you don’t have any on your to-do list, maybe you could find some useful ideas here.

    – I added multiple “windows” together. using Visibility.collapsed/Visible. So when my project starts it comes to a window “load save/start new game.”(they all do the same currently, I have yet to add any sort of save feature, but your recent lesson will help!) And then you go into a create character section. male/female, races(loaded via XML), Classes(Loaded via XML) and Attribute point assignment.
    Each section is a step. You cannot go to classes until a sex is selected. All using visibility.
    None of this is used in game(yet) however just setting up the layout to be used.
    – I added music. I have a bug where the music doesn’t loop, but it is nice to have I feel.
    – I added a change – when you press escape OR the x, the program doesn’t close. instead a “menu” pops up. save/load/continue/exit with a popup confirmation “are you sure?”
    (known bug – the popup is in the center of the computer monitor, NOT the center of the game screen)
    – changed items some to have a “buyPrice” and a sellPrice” And at one point had the trade screen show the min and max damage: sword dmg 4-7 buyPrice: 20
    However moving damage around at one point broke that and I have yet to fix that part.(which is when I decided to focus on doing things outside your path)
    Plus a lot of other minor tweaks.

    All in all thank you for this, and please keep it up as you are able!

    1. You’re welcome, Bill

      Wow! Those are a lot of cool changes. I added them to the project list. By the way, now there is a “Suggested” column, for anyone to add their ideas for future enhancements. Let me know if you try it out and if there are any problems with it. I’m still learning some of the GitHub capabilities.

      For the non-centered MessageBox, something I’ve done in other programs is to create a new Window class that accepts a title and message in its constructor. Then, it does its own Yes/No handling. You can check out the code at: The WindowStartupLocation causes it to center in its owner’s window (which is set on line 3 of the SampleCallingCode).

      At some point, I need to plan for converting this program to .NET 5 (the replacement for .NET Core and .NET Framework that should come around November 2020) and to make it more open to other people contributing code.

      I’ve already got most of the code written for the next lesson (removing unused properties from the save game serialization). But, an old client of mine needed me to add a new feature to an app I wrote for them.

      Take care!

  6. Thank you for the suggestion Scott, I will definitely take a look at your example when I have a chance.
    4 things –
    1 – 1 am unable to add/edit/suggest anything to your suggested list. I am also new to git so it could be myself doing something wrong.

    2 – bug? I noticed this a long time ago. but the Monster Chance of encountering does not work.(unless I misunderstand it or am doing it wrong). When I first was playing around I tried changing the percent to 25 or 50 from the default 100 you set, and nothing changes. There is always a monster there, and when you kill one there is always a new monster.

    3 – suggestion – improved monster encounters. Multiple of the same monster, each allowed to hit? 3 spiders? being able to set how many of each monster can spawn. Like only ever 1 dragon, but maybe up to 4 goblins. NOT having a new monster insta-spawn upon killing the last, Only when re-entering the location.
    NOT being able to run/move away. You need to select “run” or “escape” and you have a chance of failure. If you fail, that was your attack and the monster attacks next.

    4 – suggestion. this is related to the last, but different. and maybe refactoring needed: change locations to have % chance of monster spawn here.(which would make the bug above moot) And add to locations a Monster table of sorts.
    example: table 1 – 50% chance spider, 30% chance snake, 20% chance rat
    table 2 – 50% chance Goblin, 48% chance orc, 2% chance Dragon

    And location 1 has table 1 assigned, location 2 and 3 have table 2. And IF a monster is spawned, it is based on the loot table. So multiple monsters can spawn multiple places but randomly. If you want 100% spawn rate just have a table that is: spider: 100%.
    And as you need more monster tables, just create and load via an XML/Json?

    1. Hi Bill,

      1. I probably need to set some permissions, to let other people add tasks.
      2. Currently, if you go to a Location that has any monsters in the MonstersHere property, you will 100% have a monster to fight. The ChanceOfEncountering is used to determine which monster in the MonstersHere list that will be instantiated. I think that’s what you described in #4. We could add a ChanceOfMonster property to Lcoation, to determine if there is any monster instantiated at all.
      3. I added a task for the combat options. Someone added some of those features to their version at, if you want to check that out. I’ll have to think about having multiple monsters to fight at the same time. It can be done, but if we get to the graphics stage, that might be difficult to display.

  7. Scott,

    Found that if you modify the GameData XML files make sure you clean solution under the build options. Seams the old xml files don’t get updated even if the property Copy to Output Directory is set to Copy always. Grr after stepping through was like why is this not updating. Should the Build Action property be set to Content? I tried None also and got same result.


    1. Sometimes Visual Studio is like that. I remember it having a problem with web applications. If you only changed the UI code, it didn’t always recognize it needed to update that file in the build. :/

      I was just testing a few options, and it seems like “Content” -> “Copy Always” worked the best.

  8. Hi Scott:
    I’m having an issue loading the images at runtime. I am using visual Studio 2019 which may be the issue here. I created the folders “Images/Locations” and copied all the images to the locations folder. I selected the images and changed the Build Action to Resource. When I run the program none of the images show up. I copied the source from the lesson and used it after trying to make my code work. The only workaround I have at this time is to hard code the physical path into the WorldFactory which isn’t the correct way to do this. Some threads say to change the build action to content but that doesn’t work either. Are you aware of any issues when using VS2019?

    Thanks much and I am really enjoying this course!


    1. Hi David,

      Usually when this happens, it’s because the Engine project was created as .NET Core or .NET Standard, not .NET Framework. Can you upload your solution (including the directories under it, and all the files in those directories) to GitHub or Dropbox, so I can look at it?

  9. Scott, thank you so much for writing these lessons! I’m a Python programmer learning C# for games and already completed your previous lessons in the old Windows Forms track. I enjoyed it and it gave me a lot to think about for RPG design that I hadn’t ever considered. Now I really want to try the WPF track, but it looks like ‘Lesson 03.1: Creating the Solution and Game Screen’ might be producing a WordPress error and failing to load. The other lessons seem to work fine so far, though. Please help, and thank you!

    1. You’re welcome, Emma!

      My web server was upgraded yesterday, and it looks like a few pages are broken. I’ll check it out after work today and try to get it fixed.

    2. This pages should be working again. I need to apply a new code-formatting function, to get the line numbers page for the source code. But, I think the pages are all working now, and displaying the source code.

  10. Hey Scott,

    Just passing by to express gratitude for your course and lessons. I especially like learning C# with an RPG context. It makes learning extra fun. The videos were exceptionally well made as well.Once I get better I’d like to contribute when possible.

    For conversation sake, have you ever played MUDs? The sheer amount of detail that can be implemented in a MUD makes it the best rpg experience I’ve ever had. Learning your game will be as close to coding a MUD as I can get right now. Maybe my ultimate goal would be a browser based game that is text-based like a MUD, with an updating map of player movement.

    Once again, thank you for courses – I’ll be looking forward to your future lessons and posts and will post more in the future. Best Regards,


    1. Thanks Rob!

      I never played MUDs. I played most of the old MMORPGs (Ultima Online, Asheron’s Call, Everquest, etc.). Before that, I played almost all the Infocom text games and games like The Bard’s Tale.

      One of the fundamental ideas behind this game is to make it flexible, allowing developers to modify it however they want. This is obvious for the locations, monster, game items, etc. But, I’d like to make it so customized actions can be added – although that’s still a while before getting to that.

      My project at my current client ends this Friday, and they aren’t starting anything new right now. So, I should have time to get back to this project and some other ideas I’ve had.

  11. Not many tutorials have taught me as much as yours have, granted I’ve only done the (OLD) one. Thank you for all of your work.

  12. I feel like maybe I’m missing something super simple but. In 5.1, where we make a static, factory class to churn out items, when is the static, item factory constructor called?

    Is it on runtime or when the code pokes at the properties or methods in that static class?

  13. I really appreciate the reply, one more question! At least that I can think of for right now. when the static ItemFactory() constructor is called, gives the _standardGameItems variable the value of a list and then populates that list.

    Does that list vanish whenever we’re done using the ItemFactory class? Or does the pointer hold the list until we tell it otherwise?

Leave a Reply

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