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. Rens
    Rens February 12, 2022

    I just got to chapter 18 and started doing some “free-coding”. I’m trying to add images when a weapon/healing changes or when a monster appears but I can’t get it to work. Am I just not good enough or is this something that can’t be done?
    Love this tutorial btw

    • Scott Lilly
      Scott Lilly February 12, 2022

      Hi Rens,

      Can you upload your solution (including the directories under it, and all the files in those directories) to GitHub, Dropbox, or some other file-sharing location so I can look at it?

      Can you also tell me more about the change you’re trying to make? What images are you trying to change (monsters, locations, new types of images)? Do you get an error message, or are the images not displaying?

      I might not be able to look at the code until Monday. I’m working on some changes for a client this weekend.

      • Rens
        Rens February 13, 2022

        Hi Scott

        I would like a picture of that monster to appear when that monster appears (a rat appears a picture of a rat appears, …). Same for the locations, healing items and weapons (maybe Items too but I’m not sure what use that would be).

        Yesterday when I sent my previous message, I had uploaded the weapons pictures to Properties.Resources in Engine. I didn’t get any errors then, but the picture didn’t appear. I thought ‘That’s a Future me problem’, deleted the code and continued with your guide.

        Now that I’ve seen your reply, I’ve put that code back but I get an error (I’ve put this in comment and it’s in UpdateWeaponListInUI())

        Thank you for your reply and no problem if you can’t look directly at my code. (I’m already happy that you want to help tbh)


        • Scott Lilly
          Scott Lilly February 14, 2022

          Hi Rens,

          I made some changes and have them at:

          The World.cs and HealingPotion.cs changes are only to add the potion’s image.

          In Form1.cs, the basic changes were to make sure the weapon and healing potion images were dropped when the player’s selected weapon selected healing potion are changed.
          Line 281: Populates the player’s CurrentWeapon property.
          Line 286: Sets the picture box’s Image property to the player’s CurrentWeapon’s Picture. The “?” prevents an error if the player’s CurrentWeapon is null.
          Line 307: Clears the healing potion’s picture if there are no healing potions in the player’s inventory.
          Line 316: Populates the healing potion’s picture if there is a healing potion in the player’s inventory.
          Line 495: Populates the weapon’s image when the player selects a different weapon from the weapons combobox.

          Please let me know if there are any problems with those changes, or if you have any questions about them.

          • Rens
            Rens February 22, 2022

            Hey scott
            Sorry for the late reply, some school work got in the way.
            I’ve included your code in my solution, but since I’ve already continued working on the tutorial, the logic code is now separated from the UI, so the img code doesn’t work 100% anymore. I’d be very happy if you could take another look. I accidentally broke my Git so here’s the new link:
            thanks in advance

          • Scott Lilly
            Scott Lilly February 24, 2022

            Hi Rens,

            I have an update at:

            Check lines 74-105 and the new event handling function for cboPotions.SelectedIndexChanged on lines 228-231.

            The basic idea is that the eventhandlers for the combobox SelectedIndexChanged events are set up before populating the comboboxes’ DataSource properties. When you set the DataSource, if there are any items, then the first one is “selected” by default. If the event handlers are not setup before setting the DataSource, then the SelectedIndexChanged is not detected when the default (first) option is selected.

  2. zh
    zh April 30, 2022

    Hello, how can I add sound effects to the game. I want the game to play various sound effects when performing different actions. Thanks for the tutorial. It helped me a lot to learn C#. Sorry, my English is not very good, there may be places that are not clear.

  3. Marco
    Marco August 18, 2022

    Hi Scott,
    Great tutorial! Just a beginner info: should I start from this one or the new tutorial on soscsrpg?
    Would it be useful to study both of them in sequence or will this lead to confusion?

    Thanks very much!

    • Scott Lilly
      Scott Lilly August 18, 2022

      Hi Marco,

      It’s probably best to start with the newer guide at SOSCSRPG. Those lessons do start a little quicker, and might be easier if you already understand some basic programming concepts – like classes, objects, and properties. But, if something is not clear in one of those lessons, you might look at the related lesson here for more details (or leave a question on the SOSCSRPG lesson).

      • Marco
        Marco August 18, 2022

        Dear Scott
        thank you very much for the quick reply!

  4. John
    John September 29, 2022

    I’ve followed the all the the entire way through the guide and I end up with not being able to use the game because it crashes when I try and select a weapon or a potion from drop down menu.

    Where I get the error:
    int damageToMonster = RandomNumberGenerator.NumberBetween(currentWeapon.MinimumDamage, currentWeapon.MaximumDamage);

    System.NullReferenceException: ‘Object reference not set to an instance of an object.’

    • Scott Lilly
      Scott Lilly September 29, 2022

      Can you upload your solution (including the directories under it, and all the files in those directories) to GitHub, Dropbox, or some other file-sharing location so I can look at it?

  5. Matthew
    Matthew November 21, 2022

    Hi Scott, hope this finds you well.

    I am attempting to create my own basic RPG battle sim for fun using this tutorial as a base. I’ve gotten a bit stumped trying to pass the list generated in my ItemCollection project into my main BattleScreen project. Additionally, there’s an error in my player class where the AddItemToInventory subroutine isn’t retrieving the ID for an InventoryItem. I have tried a lot of things but nothing has worked. You’ll find attatched the github repository below if you could please take a look. Any help would be much appreciated.

    • Scott Lilly
      Scott Lilly November 21, 2022

      Hi Matthew,

      Can you give more information about “trying to pass the list generated in the ItemCollection into the BattleScreen”? ItemCollection is a static class, with static methods, so the BattleScreen class should only need to call ItemCollection.ItemByID() or ItemCollection.CPUByID() to get each item or CPU object from ItemCollection. If you want to display the items currently in the Player’s inventory, the BattleScreen class would do that by using the Player1.Inventory.

      I don’t see an obvious problem with the AddItemToInventory function, but it’s difficult to diagnose without being able to run the program. I did notice the ItemCollection.GenerateItems() function does not create an item for ITEMID_SkipCard.

      Do you see an error message in Visual Studio, when the error happens in AddItemToInventory? If so, knowing that error message would help. Also, there is a “stack trace” (link shows more information on stack traces) that tell you exactly where the error happened. That information might help me track down the source of the error.

      If I could build the complete solution and run it myself, that would help me find the source of the error (if the error message and stack trace don’t help you find it). Can you upload the complete solution to GitHub? If you haven’t uploaded a solution to GitHub before, here is some information (and a video) on how to do that and share it with me.

  6. Alain
    Alain January 4, 2023

    I did all the lessons and now i have a pc crash and lost everything.
    Is it possible to have the whole code source in zip file?
    Thank you.

  7. Alain
    Alain January 9, 2023

    Hi Scott,

    Thank you.
    I have all the project.

  8. Dylan
    Dylan March 3, 2023

    Hi Scott,
    I have been thoroughly enjoying this tutorial, but I have just completed step 16.1 and had not built the program in a while, but my location buttons do not seem to be working. i was wondering if you could take a glance and let me know if i am overlooking, missing, or simply just deleted the wrong something while attempting to refactor the code.
    i even tries changing my starting location and the buttons still don’t work.

    thank you for everything,

    • Scott Lilly
      Scott Lilly March 5, 2023

      Hi Dylan,

      It looks like the problem is that the buttons are missing their “eventhandlers”. This is the line of code that lets the program know what function to run when the player clicks the buttons. You can see how eventhandlers work, and how to add them to your current code, here in lesson 21.3

      Please let me know if that doesn’t help you get the buttons connected to the movement functions.

  9. Jim Steel
    Jim Steel March 6, 2023

    Hi, I do not have Windows and was planning on using Linux to go through this tutorial. Is it possible to follow through with this on Linux or is there Windows-specific code along the way.

    I did try and look through, but I’m unfamiliar with C# so I wasn’t too sure.

    • Scott Lilly
      Scott Lilly March 6, 2023

      Hi Jim.

      Unfortunately, these lessons will not work on Linux or Mac. You can use .NET Core or .NET 5/6/7 to write things in C# that will run on Windows, Linux, and Mac. However, WinForms (what this program uses) and WPF (another way of writing C# desktop programs) will not work on anything other than Windows.

      If you want to write games, there are some game engines that use C#. The popular ones are Unity 3D, Godot, and MonoGame. You can find out more about them here:

      If you’re interested in writing websites in C#, the latest Microsoft technology is Blazor Server and Blazor WASM. Because those are used to write programs that run in a browser, they work on all computers.

Leave a Reply

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