Press "Enter" to skip to content

Learn C# by Building a Simple RPG

Giant Spider!
Mandatory Giant Spider!

If you want to write a Role Playing Game, but don’t know how to program, or just want to learn how to program in C#, then you’re at right the place.

These lessons will take you from a complete beginner, to being an author of a Role Playing Game, for free.

This isn’t the world’s greatest game. In fact, it’s very short and kind of ugly.

However, as you create it, you’ll learn the most common C# programming practices and techniques. Then, if you want, you can improve the game, adding more features and your own special touch to it.


NOTE: If you already know the basics of C# programming (classes, properties, functions, “if” statements, etc.), you might want to look at the newer “Build a C#/WPF RPG” lessons. The code in those lessons is more like how I would write a “real” professional program – using better design and architecture.



Lesson 00.1 – What is in these lessons?

Lesson 00.2 – General information about programming in C#

Lesson 00.3 – The parts of Visual Studio

Lesson 01.1 – Defining classes and objects for the game

Lesson 02.1 – Installing Visual Studio Community Edition

Lesson 02.2 – Building the solution for the game

Lesson 03.1 – Building the first screen

Lesson 04.1 – Creating the Player class and its properties

Lesson 05.1 – Creating objects from classes

Lesson 06.1 – Creating the remaining classes

Lesson 07.1 – Inheritance and base classes

Lesson 08.1 – Setting properties with a class constructor

Lesson 08.2 – Using class constructors with derived classes

Lesson 09.1 – Using your classes as datatypes

Lesson 10.1 – Creating collections of objects

Lesson 11.1 – Using a static class

Lesson 12.1 – Add the remaining UI controls

Lesson 13.1 – Functions, procedures, and methods

Lesson 13.2 – Creating functions to handle user input

Lesson 14.1 – Variables

Lesson 14.2 – If statements

Lesson 14.3 – Foreach loops

Lesson 15.1 – Getting random numbers for the game

Lesson 16.1 – Writing the function to move the player

Lesson 16.2 – Refactoring the player movement function

Lesson 16.3 – Functions to use weapons and potions

Lesson 17.1 – Running the game on another computer

Lesson 18.1 – Future enhancements for the game

Bonus lessons (enhancements to the game)

Lesson 19.1 – Scroll to the bottom of a rich text box

Lesson 19.2 – Use a calculated value for a property

Lesson 19.3 – Clean up the source code by converting foreach to LINQ

Lesson 19.4 – Saving and loading the player information

Lesson 19.5 – Changing dropdown default values

Lesson 19.6 – Increase maximum hit points when the player gains a level

Improving SuperAdventure’s code quality by refactoring

Lesson 20.1 – Refactoring the SuperAdventure program

Lesson 20.2 – Binding a custom object’s properties to UI controls

Lesson 20.3 – Binding list properties to datagridviews

Lesson 20.4 – Binding child list properties to a combobox

Lesson 20.5 – Moving the game logic functions from the UI project to the Engine project

Adding a vendor to locations (with buying and selling items)

Lesson 21.0 – Plans for adding a vendor to locations

Lesson 21.1 – Adding a price to game items

Lesson 21.2 – Create the vendor class and add it to locations

Lesson 21.3 – Add a button and create its eventhandler in code, without the UI design screen

Lesson 21.4 – Completing the trading screen

Use SQL to save and restore player’s game data

Lesson 22.1 – Installing MS SQL Server on your computer

Lesson 22.2 – Creating database tables from classes

Lesson 22.3 – Creating the SQL to save and load the saved game data

Creating a console UI for SuperAdventure

Lesson 23.1 – Creating a console front-end for the game

Final refactoring (cleanup) of the SuperAdventure source code

Lesson 24.1 – Make the SuperAdventure source code easier to understand and modify

New game features

Lesson 25.1 – Select a random monster at a location

Lesson 26.1 Displaying a World Map

Lesson 26.2 – Hiding Unvisited Locations on the World Map


Bug Fixes

Lesson 99.1 – Preventing duplicate quests

Lesson 99.2 – Setting CurrentWeapon when the player has multiple weapons


Share your personal, expanded versions of SuperAdventure here!


  1. Collin
    Collin August 8, 2015

    I have 69 random build errors after finishing the tutorial. Any way I can get source code for the finished game?

  2. Senpai
    Senpai August 11, 2015

    Hey there Scott,

    i can’t figure out how to properly add the health scaling per level. I tried the “AddExperience(int experiencePoints)” function you mentioned in another comment but I can’t get any further.
    While im adding new Items, Monster, Location and Quests, i really need to be able to raise player health at some point.
    A source code for the health increase per lvl would be awesome if that’s not too much to ask :p

    I really enjoyed your tutorial and it tought me a lot so far.

    Thank you!

  3. Senpai
    Senpai August 24, 2015

    Thank you very much!

    Now ill be able to add level requierements for my locations. 😀


    Have a nice day!


  4. Sarah
    Sarah August 31, 2015

    Hi Scott,

    i’d like to show all the movement buttons at any given time but grey out those, that can’t be used for the current location. How do I do this? Would be cool if you could help me with some specific source code :p.


    Thank you!

    • Sarah
      Sarah August 31, 2015

      woops, never mind, just changed .Visble to .Enabled, didn’t think it would be that easy, sorry :p

      But another thing:

      I’m trying to get the UI resized when the user is changing the window size, can’t get it to work as I want it to D:

      thanks again!

      • Scott Lilly
        Scott Lilly August 31, 2015

        Hi Sarah,

        Good job on finding the property! If you’re going to work a lot with the UI, you should take a look at the other properties and events on the different UI controls. That will make you familiar with what you can do to them.

        To resize items, you’ll want to use the “Anchor” property. That will let you say something like (for example), “no matter how big the form is, I want this button to stay 10 pixels from the right edge and bottom edge”. You may run into a problem if you want controls to stay a certain size from the center of a form. Then you’d need to do something like put a splitter control on the form, and put the other controls (buttons, datagrids, etc.) inside the splitter panels.

        There is also the form’s OnResize event. You can hook an event handler to that event. Then, when the user changes the form’s size, you can have a function that will adjust the controls. However, that can get a little complex – especially if you have a lot of controls on the form.

  5. Joerg
    Joerg September 23, 2015

    Great tutorial. Just one little question: do the videos come without sound or are my sound settings misbehaving?

    • Scott Lilly
      Scott Lilly September 23, 2015

      Thanks. The only video with sound is the one for installing Visual Studio. My old apartment was so noisy, it was difficult to record audio.

  6. Joe D
    Joe D September 28, 2015

    Have been away from from C# for  several years. I am a retired truck driver. I wrote a small simple wargame about 4 years ago, VS express has changed a lot and my mind is like a sieve. Am going to try to get my feet wet with VS 2015 using your tutorial.

    wish me well, Joe

    • Scott Lilly
      Scott Lilly September 28, 2015

      Good luck, Joe! If you have any questions along the way, please leave a comment. I can usually answer them within a day or two.

  7. Christopher
    Christopher October 3, 2015

    This is exactly what I needed before I step into unity.  This will give a great foundation I can use in the future.  Thanks

  8. Meds
    Meds October 13, 2015


    I followed this a little while ago and added simple levelling and then tried using progress bars to represent health and exp (which is pretty bad when moving OS enviroments. it worked fine on vista did what I expected then on windows 7 it didn’t behave the same which is a shame) unfortunately I lost all that code due to a HDD failure and have only now some years later download your source code to start again. So thank you for the work you have done it is definitely the only resource of this type available and if time permits it you should do more!!

    Now, I’ve been toying with the idea of having a map for the locations shown to you. I was thinking of drawing a few small square tiles that just have a solid border but then gaps that show the directions you can move too. Do you reckon this is possible without completely re-doing your location and movement code?

    • Scott Lilly
      Scott Lilly October 13, 2015

      Thanks. I’m currently working on a series of videos for setting up a .Net development environment, with Visual Studio Community 2015 and Windows 10. Once that’s done, I’m going to continue on with a more advanced version of the game that I started on a while back (you can see it here on GitHub).

      To add a simple graphic map to the game, I started playing around with an idea of adding an X and Y coordinate to the Location class. Then, I’d also have property to hold the name of a graphic file to use for the location (forest, house, lake, mountain, etc.). Then, I’d add a control to the UI to hold a 9 x 9 grid of these images (each one probably a 50 pixel square). The player would always be drawn in the center square, and I’d display the graphics for the nearby locations. You can see the idea I had here: I want to do this app in WPF, so I can get more experience with doing front-end XAML work.

  9. Aleksandar
    Aleksandar October 18, 2015

    Your course is awesome! I always looked for this! Looking forward to finish it! Thanks a lot!!!

    JAMES ORR November 3, 2015

    Hello Scott,

    I have no xp in programming of any kind, however, I have decided to make my own rpg. I found your tutorial while searching for a way to do this. What all do I need make the rpg to run C# (per your tutorial) in Windows 7? Just Visual Studio? pardon me for being an absolute beginner

    • Scott Lilly
      Scott Lilly November 3, 2015

      Hello James,

      To follow this tutorial, the only tool you need is Visual Studio Express 2013. If you are using Windows 7, you need to have Service Pack 1 (for Windows 7) installed on your computer. You can get that by running “Windows Updates” from the “Control Panel”, if you haven’t already installed it (or if Windows hasn’t already done an automatic update).

      Please let me know if you have any questions while using the tutorial.

  11. James Orr
    James Orr November 3, 2015

    Thanks so much. I was afraid there would be all kinds of things to get. I do have SP1 and forgot to mention, my system is Ultimate Edition. Now, I will acquire VSB13 and give her a test run.

  12. Vox
    Vox November 10, 2015


    I’m really excited to try this out, but I don’t have Visual Studio Express 2013 and can’t get it as my computer (Win7) will absolutely not install Service Pack 1. It’s been like this for a while and no matter what I’ve tried, it simply won’t install. So my question is, must we use Visual Studio Express 2013 for this or would VS2010 work, too?

    • Scott Lilly
      Scott Lilly November 10, 2015

      I think everything will still work with Visual Studio 2010, as long as you have the .NET Framework 3.5 (or more recent) installed. The lessons cover the basics, which should be the same. If you do have a problem, please leave a comment and I will try to help.

  13. Aviv
    Aviv November 24, 2015

    Thank you so much for this, currently on lesson 12. see you in lesson 19 and I hope you will make even more! thank you again ! you are awesome

    • Scott Lilly
      Scott Lilly November 24, 2015

      You’re welcome! I plan to make some more lessons and videos during the Thanksgiving holiday this week. At least one on writing unit tests for your code, and I have some ideas for more refactoring lessons for SuperAdventure (to make the code cleaner, and more like how I would write it in a real project).

  14. Som
    Som November 25, 2015

    Hello Sir, I just finished creating this game but for some reason I cant see my weapon use button and potion use button…. And I cant see any items in my inventory all i can do at the moment is go north west east south… I cant do any quest… Please help me…

    • Scott Lilly
      Scott Lilly November 25, 2015

      Hello. You only see the weapon “use” and potion “use” buttons when you are at a location with a monster, and if you have a weapon or potion in your inventory. Try deleting the PlayerData.xml file. It should be in the SuperAdventure\SuperAdventure\bin\Debug folder (or, \bin\Release folder, if you compile the program in “release” mode). When you delete this file, the game will reset the next time you play it, and should give you a weapon to use.

      Please let me know if that does not work, and we can check other things.

      • Som
        Som November 26, 2015

        When I go to the location with a quest in it, I cant see a monster living there. Hence, I cant do any quest. I have no clue what the reason is for this……

        • Scott Lilly
          Scott Lilly November 27, 2015

          There aren’t any monsters at the locations with quests. When you get the quest at the alchemist hut, you need to go north to the Alchemist’s Garden location. That location has monsters. If you check the PopulateLocation() function, in the World class, you’ll see the locations with monsters.

  15. Aviv
    Aviv November 26, 2015

    Hey again,

    Finished the game ! at least the basic of it, I really want to add more things to it but I have some space issues, is it possible to create another form that will pop up when i click a button. I want to add like inventory button and by clicking on it, it will open an inventory screen where you can equip, drop, sell your items, armor, weapons, etc.

    The problem I can’t get it to work. I don’t know how to show the form, I added a new form to SuperAdventure.

    can you please help me how to show up the form by clicking a button and from there I think I will be fine. thank you so much

  16. Aviv
    Aviv November 26, 2015

    I managed to get the second form to show up but there’s an entire new problem.

    _player doesn’t exist in the second form. is there a way to declare it to be available to the entire program?

    • Scott Lilly
      Scott Lilly November 27, 2015

      The _player variable is a class-level variable in the SuperAdventure form, and can only be seen in the SuperAdventure class – unless you pass it to the new form. In the constructor of your new form, you can add a parameter, to pass in the _player object when you create your new form. Then, you can use the player’s inventory, quests, etc. in the new form. So, you probably have code to handle the button press that looks somthing like this:

      MyNewForm myNewForm = new MyNewForm();

      When you add a Player parameter to your MyNewForm class, you can pass the _player object by changing your code to this:

      MyNewForm myNewForm = new MyNewForm(_player);

      Let me know if there are problems getting that to work.

  17. Aviv
    Aviv November 28, 2015

    Thank you! it does work but is there a way to update and change the text labels in the main form via the second form (by clicking on a button for example), it doesn’t let me. apart from that it works very well! I am planning to really expend the game just for practice and fun and eventually release the open source for it here so maybe more people can look at it and maybe learn  something new. but I want to add all sort of new things first!

    • Scott Lilly
      Scott Lilly November 28, 2015

      You’re welcome! I’m finishing a new lesson to show a way to update the labels when the player properties are changed from any place. I should be able to post it tomorrow, after I edit and double-check it.

  18. Aviv
    Aviv November 28, 2015

    Sorry I ask to many questions but I am going to ask one last question.

    I’ve been looking for hours for a way to draw simple 2d sprites. I found it’s possible with XNA. Do you recommend using it? I’ve read somewhere that it is dead.

    And when I try to add the XNA libraries to the game, it gives me a warning:

    Warning    2    There was a mismatch between the processor architecture of the project being built “MSIL” and the processor architecture of the reference “Microsoft.Xna.Framework.Graphics, Version=, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86”, “x86”. This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.    RPGAdventurePlus

    How do you recommend to implement very simple 2d graphics into the game?


    • Scott Lilly
      Scott Lilly November 28, 2015

      I’ve also heard that XNA is dead. Unfortunately, I don’t do a lot of work with graphics. I did write a chess-like game that used the built-in System.Drawing library. You could probably use that, and PNG or BMP graphic files, for a simple 2-D game. That’s what I’ll probably do when I re-start working on my more advanced game engine, starting next month.

      Many C# game developers use Unity 3D to handle their graphics. It can make professional-looking games.

  19. Andy
    Andy December 9, 2015

    Hey Scott, I was wondering how difficult it would be to integrate this code into Unity?

    • Scott Lilly
      Scott Lilly December 10, 2015

      I don’t know. I’ve only spent a couple hours looking at Unity. I’ll try to take a look at it this weekend.

    • Scott Lilly
      Scott Lilly December 15, 2015

      I saw some Unity code, and it doesn’t look like it would be easy to get SuperAdventure to work in Unity. Once I have all the logic code out of the UI, I plan to show how to have the Engine project work with Windows Forms, WPF, and ASP.Net front ends (without any changes). I’ll try to get it to work with Unity, but I’m not sure if that will be possible.

  20. Matthew
    Matthew December 10, 2015

    Hey Scott, so I finished up your tutorial and now I am working on making the game on my own and adding more features. Couple questions. First is how would I go about adding a hit/miss feature, that has different things affect it (player stats, monster stats, and weapon stats). Also I would like to add a way to use armor. Where if hit, then the armor takes away a fraction of the damage. Like instead of taking 5 damage I might take 2 damage. Thank you for your help!

    • Scott Lilly
      Scott Lilly December 10, 2015

      Hi Matthew,

      The btnUseWeapon_Click function of SuperAdventure.cs is where we do the combat. So, you’d want to change that.

      To add a hit/miss, I’d change the code near this line:
      int damageToMonster = RandomNumberGenerator.NumberBetween(currentWeapon.MinimumDamage, currentWeapon.MaximumDamage);
      to be surrounded by an “if” statement, to see if the player hits the monster. A simple one could be like this:
      if(RandomNumberGenerator.NumberBetween(1,100) > 50)
      int damageToMonster = RandomNumberGenerator.NumberBetween(currentWeapon.MinimumDamage, currentWeapon.MaximumDamage);
      _currentMonster.CurrentHitPoints -= damageToMonster;
      rtbMessages.Text += "You hit the " + _currentMonster.Name + " for " + damageToMonster.ToString() + " points." + Environment.NewLine;
      rtbMessages.Text += "You attacked the " + _currentMonster.Name + " and missed." + Environment.NewLine;

      That would give the player a 50% chance of hitting the monster. You could make it even more complex by doing something like giving the monsters levels, and changing the 50 (for the “hit” percentage) to be 50 +/- the difference between the monster’s level and the player’s level, or bonuses on weapons/armor/jewelry/etc.

      To change the amount of damage the player takes, because they’re wearing armor, you’ll need to change this line:
      int damageToPlayer = RandomNumberGenerator.NumberBetween(0, _currentMonster.MaximumDamage);

      • Matthew
        Matthew December 11, 2015

        Okay, thank you! Do you think it would be helpful to create a hitmiss function, that calculates whether or not the player hit the monster and then sends that value to the combat function? Or do you think having this as its own class in the engine library, since there will be different properties to be applied? I ask this because I want to have monster level, player level, intelligence level (I am trying to add in stats as well), to all have an influence on whether or not the monster is hit. And then to see if the monster hits the player it will be monster level, player level, and dexterity level.

        Thanks again!

        • Scott Lilly
          Scott Lilly December 11, 2015

          I saw your other comments, and that you got this working. I think this is a good way to handle combat. If you expand the game to include things like magic spells, poisons, etc., you can add new functions to the class to handle those different ways of attacking.

Leave a Reply

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