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:

https://github.com/ScottLilly/SOSCSRPG

 

Overview

Lesson 00.1: Overview

 

Preparation

Lesson 01.1: Installing Visual Studio Community 2015 – Update 3

Lesson 01.2: Installing TortoiseSVN and VisualSVN

 

Planning

Lesson 02.1: Planning the Game

 

Programming

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

 

Cleanup

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

171 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.

    THANK YOU!

  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!

    Thanks,

    Gary

    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: https://github.com/ScottLilly/SOSCSRPG/projects/1. If you have an idea to add, please let me know.

      Take care!
      Scott

      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?

        Regards,
        James

        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? https://devblogs.microsoft.com/dotnet/introducing-net-5/

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

            Thanks,
            James

          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: https://gist.github.com/ScottLilly/962f5de53ddfc3e7dc5941a96f5f4ba8 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!
      Scott

  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 https://github.com/Skollow/NCSOSCRPG, 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.

    James

    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!

    Dave

    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.

Leave a Reply

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