Press "Enter" to skip to content

Lesson 11.1 – Using a static class

Lesson Objectives

At the end of this lesson, you will know…

  • What a static class is, and how to create one.
  • When you want, and don’t want, to use static classes

 

What is a static class?

All the classes we’ve created so far have been public classes. That means they are visible in all of your program. However, in order to use one of them, you need to create an object of the class. Then you work with that object.

A static class is one that is always available to the rest of your program – you don’t need to create an object from it. In fact, you can’t create an object from a static class. It’s just there.

A static class is a place to hold shared resources (variables and methods), since there will only be the one “instance” of it, and everything else in your program will use that one, shared set of methods and variables.

 

Why would you need a static class?

For our game, we need to store some things that will be used in several places in the program.

Things like the list of locations, the types of items, the types of monsters, etc. This information is never going to change. We’re going to populate these lists at the start of the game, and never change it. We’re also going to use those lists in several places in the game.

Using a static class to hold all this information is one way to make all this information available everywhere.

 

When else would you use a static class?

Another thing you can do with a static class (and a static variable) is to hold values such as a system-wide counter.

Let’s say you want a program to hand out unique, sequential numbers to the people who use it.

You could create a static NumberAssigner class, with a static GetNextNumber method, that keeps track of a static _nextNumber variable.

namespace Engine
{
    public static class NumberAssigner
    {
        static int _nextNumber = 0;
        public static int GetNextNumber()
        {
            _nextNumber = (_nextNumber + 1);
            return _nextNumber;
        }
    }
}

When you start the program, _nextNumber has a value of 0.

When a user calls the GetNextNumber method, the code adds 1 to _nextNumber and returns the value (in this case, 1) to the program. The next time the GetNextNumber method is called, it adds 1 to _nextNumber (resulting in 2 this time) and returns 2 to the program.

 

What problems can happen with static classes?

The problem with static methods and variables, is that sometimes you don’t want a shared resource, you want each user to have their own copy of the object or variable.

The game we’re creating is a single-player one. So, we don’t really have a problem using static variables.

However, if we were to make a UI for this game a website on the Internet, we might have several people playing it at the same time.

So, let’s say we stored the player’s current hit points somewhere as a static variable – CurrentHitPoints.

When player A is attacked, the program would subtract their damage and change the value of CurrentHitPoints. But if a different player did something in the game (attacked a monster or healed themselves with a potion), since we only have a static, single, shared CurrentHitPoints variable, they’d be using the value from player A, and not their real current hit points value.

That’s how static classes and variables can be dangerous. When you use a static variable to hold a value, make sure it’s one that you really want to be shared for every user.

 

Populating our game world in a static class

Now that you have an understanding of static classes and variables, we’re going to create a “World” class to hold lists of all the things in our game – locations, items, monsters, and quests.

Since we’re only going to read from it, once we do the initial population of the values, it’s OK to use a static class.

Step 1: Start Visual Studio and open the solution.

Step 2: Create a new class by right-clicking on the Engine project and selecting “Add”, then “Class…”. Name the class “World.cs”

Step 3: Copy the code for the class from here: https://gist.github.com/ScottLilly/803df1021fbc404b38f5

 

What does the code do?

The purpose of the World class is to have one place to hold everything that exists in the game world. In it, we’ll have things such as the monster that exist at a location, the loot items you can collect after defeating a monster, etc. It will also show how the locations connect with each other, building our game map.

GameMap

Here is what is happening in the different parts of the World class.

Lines 11 – 14: Static list variables. These work similar to the properties in a class. We’ll populate them with all the things in our game world, then read from them in the rest of the program.

Line 16 – 42: Constants. Constants look, and work, like variables, except for one big difference – they can never have their values changed.

We’re going to use these constants, which have a sort-of English name, so we don’t have to remember the numeric ID for each of the different games objects. Without them, if we wanted to create a giant spider for the player to fight, we’d need to remember that the giant spider monster has an ID value of 2. With the constants, we can say, get me a monster where the ID equals MONSTER_ID_GIANT_SPIDER.

If you don’t fully understand how we’ll do that, it should become clearer when we get to the lesson where we start having the player move around and we need to lookup locations, quests, monsters, and items.

Lines 44 – 50: This is the static constructor. You might be thinking, “Wait! We can’t instantiate a static class, so why does it have a constructor? After all, that’s what a constructor is used for – instantiating an object!”

With a static class, the constructor code is run the first time someone uses anything in the class. So, when we start the game and want to display information about the player’s current location, and we try to get that data from the World class, the constructor method will be run, and the lists will get populated.

Inside the constructor, we call the four methods to populate the different lists. We don’t need to have separate methods, and we could have put all the code from lines 48 through 169 into the constructor. But breaking them up makes them easier to read and work with.

Lines 52 – 173: These are the methods we use to create the game objects and add them to the static lists.

By calling the Add() method on a list variable or property, we add an object to that list.

Look at line 54. Here we are adding a new Weapon object to the Items list. When we call “new Weapon()”, the constructor of the Weapon class returns a Weapon object with the parameters passed in. Since that’s all inside “Items.Add()”, that object gets added to the Items list.

You might hear that called “inlining”, since we did multiple things (created the value and added it to the list), all in one line.

On line 68, we create a new Monster object and save it to the variable “rat”. On lines 69 and 70, we add items to the (list) property of PotentialLootItems that you might find on the rat. Then, on line 80, we add the rat variable to the static Monsters list.

Lines 175 – 225: These methods are ones we can call to get values from the static lists. We could access the lists from lines 7 through 10 directly, since they are public. But these “wrapper” methods make it a little clearer exactly what we want to do.

We pass in the ID of the object we want to retrieve from its list (by using the constants from lines 16 through 42). The method will look at each item in the list (using the “foreach”) and see if the ID we passed in matches the ID of the object. If so, it returns that object to us. If we get to the end of the list, and nothing matches (which should really never happen), the method returns “null” – nothing.

 

Summary

Now we have a populated “world” for the game. We can use the static methods from this static class at any place in the rest of our program, and get the information we need about the objects in our game world.

 

World.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Engine
{
    public static class World
    {
        public static readonly List<Item> Items = new List<Item>();
        public static readonly List<Monster> Monsters = new List<Monster>();
        public static readonly List<Quest> Quests = new List<Quest>();
        public static readonly List<Location> Locations = new List<Location>();
        public const int ITEM_ID_RUSTY_SWORD = 1;
        public const int ITEM_ID_RAT_TAIL = 2;
        public const int ITEM_ID_PIECE_OF_FUR = 3;
        public const int ITEM_ID_SNAKE_FANG = 4;
        public const int ITEM_ID_SNAKESKIN = 5;
        public const int ITEM_ID_CLUB = 6;
        public const int ITEM_ID_HEALING_POTION = 7;
        public const int ITEM_ID_SPIDER_FANG = 8;
        public const int ITEM_ID_SPIDER_SILK = 9;
        public const int ITEM_ID_ADVENTURER_PASS = 10;
        public const int MONSTER_ID_RAT = 1;
        public const int MONSTER_ID_SNAKE = 2;
        public const int MONSTER_ID_GIANT_SPIDER = 3;
        public const int QUEST_ID_CLEAR_ALCHEMIST_GARDEN = 1;
        public const int QUEST_ID_CLEAR_FARMERS_FIELD = 2;
        public const int LOCATION_ID_HOME = 1;
        public const int LOCATION_ID_TOWN_SQUARE = 2;
        public const int LOCATION_ID_GUARD_POST = 3;
        public const int LOCATION_ID_ALCHEMIST_HUT = 4;
        public const int LOCATION_ID_ALCHEMISTS_GARDEN = 5;
        public const int LOCATION_ID_FARMHOUSE = 6;
        public const int LOCATION_ID_FARM_FIELD = 7;
        public const int LOCATION_ID_BRIDGE = 8;
        public const int LOCATION_ID_SPIDER_FIELD = 9;
        static World()
        {
            PopulateItems();
            PopulateMonsters();
            PopulateQuests();
            PopulateLocations();
        }
        private static void PopulateItems()
        {
            Items.Add(new Weapon(ITEM_ID_RUSTY_SWORD, "Rusty sword", "Rusty swords", 0, 5));
            Items.Add(new Item(ITEM_ID_RAT_TAIL, "Rat tail", "Rat tails"));
            Items.Add(new Item(ITEM_ID_PIECE_OF_FUR, "Piece of fur", "Pieces of fur"));
            Items.Add(new Item(ITEM_ID_SNAKE_FANG, "Snake fang", "Snake fangs"));
            Items.Add(new Item(ITEM_ID_SNAKESKIN, "Snakeskin", "Snakeskins"));
            Items.Add(new Weapon(ITEM_ID_CLUB, "Club", "Clubs", 3, 10));
            Items.Add(new HealingPotion(ITEM_ID_HEALING_POTION, "Healing potion", "Healing potions", 5));
            Items.Add(new Item(ITEM_ID_SPIDER_FANG, "Spider fang", "Spider fangs"));
            Items.Add(new Item(ITEM_ID_SPIDER_SILK, "Spider silk", "Spider silks"));
            Items.Add(new Item(ITEM_ID_ADVENTURER_PASS, "Adventurer pass", "Adventurer passes"));
        }
        private static void PopulateMonsters()
        {
            Monster rat = new Monster(MONSTER_ID_RAT, "Rat", 5, 3, 10, 3, 3);
            rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_RAT_TAIL), 75, false));
            rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_PIECE_OF_FUR), 75, true));
            Monster snake = new Monster(MONSTER_ID_SNAKE, "Snake", 5, 3, 10, 3, 3);
            snake.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SNAKE_FANG), 75, false));
            snake.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SNAKESKIN), 75, true));
            Monster giantSpider = new Monster(MONSTER_ID_GIANT_SPIDER, "Giant spider", 20, 5, 40, 10, 10);
            giantSpider.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SPIDER_FANG), 75, true));
            giantSpider.LootTable.Add(new LootItem(ItemByID(ITEM_ID_SPIDER_SILK), 25, false));
            Monsters.Add(rat);
            Monsters.Add(snake);
            Monsters.Add(giantSpider);
        }
        private static void PopulateQuests()
        {
            Quest clearAlchemistGarden =
                new Quest(
                    QUEST_ID_CLEAR_ALCHEMIST_GARDEN,
                    "Clear the alchemist's garden",
                    "Kill rats in the alchemist's garden and bring back 3 rat tails. You will receive a healing potion and 10 gold pieces.", 20, 10);
            clearAlchemistGarden.QuestCompletionItems.Add(new QuestCompletionItem(ItemByID(ITEM_ID_RAT_TAIL), 3));
            clearAlchemistGarden.RewardItem = ItemByID(ITEM_ID_HEALING_POTION);
            Quest clearFarmersField =
                new Quest(
                    QUEST_ID_CLEAR_FARMERS_FIELD,
                    "Clear the farmer's field",
                    "Kill snakes in the farmer's field and bring back 3 snake fangs. You will receive an adventurer's pass and 20 gold pieces.", 20, 20);
            clearFarmersField.QuestCompletionItems.Add(new QuestCompletionItem(ItemByID(ITEM_ID_SNAKE_FANG), 3));
            clearFarmersField.RewardItem = ItemByID(ITEM_ID_ADVENTURER_PASS);
            Quests.Add(clearAlchemistGarden);
            Quests.Add(clearFarmersField);
        }
        private static void PopulateLocations()
        {
            // Create each location
            Location home = new Location(LOCATION_ID_HOME, "Home", "Your house. You really need to clean up the place.");
            Location townSquare = new Location(LOCATION_ID_TOWN_SQUARE, "Town square", "You see a fountain.");
            Location alchemistHut = new Location(LOCATION_ID_ALCHEMIST_HUT, "Alchemist's hut", "There are many strange plants on the shelves.");
            alchemistHut.QuestAvailableHere = QuestByID(QUEST_ID_CLEAR_ALCHEMIST_GARDEN);
            Location alchemistsGarden = new Location(LOCATION_ID_ALCHEMISTS_GARDEN, "Alchemist's garden", "Many plants are growing here.");
            alchemistsGarden.MonsterLivingHere = MonsterByID(MONSTER_ID_RAT);
            Location farmhouse = new Location(LOCATION_ID_FARMHOUSE, "Farmhouse", "There is a small farmhouse, with a farmer in front.");
            farmhouse.QuestAvailableHere = QuestByID(QUEST_ID_CLEAR_FARMERS_FIELD);
            Location farmersField = new Location(LOCATION_ID_FARM_FIELD, "Farmer's field", "You see rows of vegetables growing here.");
            farmersField.MonsterLivingHere = MonsterByID(MONSTER_ID_SNAKE);
            Location guardPost = new Location(LOCATION_ID_GUARD_POST, "Guard post", "There is a large, tough-looking guard here.", ItemByID(ITEM_ID_ADVENTURER_PASS));
            Location bridge = new Location(LOCATION_ID_BRIDGE, "Bridge", "A stone bridge crosses a wide river.");
            Location spiderField = new Location(LOCATION_ID_SPIDER_FIELD, "Forest", "You see spider webs covering covering the trees in this forest.");
            spiderField.MonsterLivingHere = MonsterByID(MONSTER_ID_GIANT_SPIDER);
            // Link the locations together
            home.LocationToNorth = townSquare;
            townSquare.LocationToNorth = alchemistHut;
            townSquare.LocationToSouth = home;
            townSquare.LocationToEast = guardPost;
            townSquare.LocationToWest = farmhouse;
            farmhouse.LocationToEast = townSquare;
            farmhouse.LocationToWest = farmersField;
            farmersField.LocationToEast = farmhouse;
            alchemistHut.LocationToSouth = townSquare;
            alchemistHut.LocationToNorth = alchemistsGarden;
            alchemistsGarden.LocationToSouth = alchemistHut;
            guardPost.LocationToEast = bridge;
            guardPost.LocationToWest = townSquare;
            bridge.LocationToWest = guardPost;
            bridge.LocationToEast = spiderField;
            spiderField.LocationToWest = bridge;
            // Add the locations to the static list
            Locations.Add(home);
            Locations.Add(townSquare);
            Locations.Add(guardPost);
            Locations.Add(alchemistHut);
            Locations.Add(alchemistsGarden);
            Locations.Add(farmhouse);
            Locations.Add(farmersField);
            Locations.Add(bridge);
            Locations.Add(spiderField);
        }
        public static Item ItemByID(int id)
        {
            foreach(Item item in Items)
            {
                if(item.ID == id)
                {
                    return item;
                }
            }
            return null;
        }
        public static Monster MonsterByID(int id)
        {
            foreach(Monster monster in Monsters)
            {
                if(monster.ID == id)
                {
                    return monster;
                }
            }
            return null;
        }
        public static Quest QuestByID(int id)
        {
            foreach(Quest quest in Quests)
            {
                if(quest.ID == id)
                {
                    return quest;
                }
            }
            return null;
        }
        public static Location LocationByID(int id)
        {
            foreach(Location location in Locations)
            {
                if(location.ID == id)
                {
                    return location;
                }
            }
            return null;
        }
    }
}

 

Source code for this lesson

Source code on GitHub

Source code on Dropbox

 

Next Lesson: Lesson 12.1 – Add the remaining UI controls

Previous lesson: Lesson 10.1 – Creating collections of objects

All lessons: Learn C# by Building a Simple RPG Index

160 Comments

  1. Matt
    Matt December 26, 2016

    Hey, I seem to be having problems with anything that uses “ItemByID”. For example…

    rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_RAT_TAIL), 75, false));

    …ItemByID will always be marked as an error, saying that “the item ‘ItemByID’ does not exist in the current context.” I’ve gone over all my previous code, and checked it against yours, but from what I’ve seen, everything looks fine.

    What could my issue be?

  2. Matt
    Matt December 27, 2016

    Nevermind! All this time, I thought I had made a mistake somewhere in the previously written code, when all I was doing was getting ahead of myself.

    Oh well. All that searching and digging helped me learn a bit. I’ll chalk that up as win for me.

    Merry belated Christmas, and thanks for the tutorial. 😀

    • Scott Lilly
      Scott Lilly December 27, 2016

      Cool (finding the solution on your own).

      I hope you had a good Christmas, too.

  3. Lukasz
    Lukasz December 28, 2016

    Hi Scott,

    Great tutorial, much appreciated!

    Could you tell me we are setting quests in a given location below the constructor instead inside of it?

    Thank you.

    • Scott Lilly
      Scott Lilly December 29, 2016

      You’re welcome

      All locations do not have a quest. So, I did not put a Quest parameter in the Location constructor. You could add a Quest parameter, and pass in “null”, or make it an optional parameter. But for this code, I chose to add the quest this way – just my preference for here. The other ways would work just as well.

  4. Johan
    Johan January 4, 2017

    Hi Scott!

    Great tutorials.

     

    I was a bit lazy in the end and copied alot, got some errors which i solved.

    Although i still got 2 more errors in the World.cs on line 88 and 98 “Quest clearAlchemistGarden =
    new Quest(
    QUEST_ID_CLEAR_ALCHEMIST_GARDEN,
    “Clear the alchemist’s garden”,
    “Kill rats in the alchemist’s garden and bring back 3 rat tails. You will receive a healing potion and 10 gold pieces.”, 20, 10);

     

    Line 98 is the same error, so there is only one thing to fix, although i cant figure it out.

     

    The error message is “There is no argument given that corresponds to the required formal parameter ‘rewardItem’ of ‘Quest.Quest(int,string,string,int,int,Item)’

     

    Any help would be appreciated.

     

    Sincerely/ Johan

    • Scott Lilly
      Scott Lilly January 4, 2017

      Thank you, Johan!

      That error message shows the Quest constructor expects six parameters – the “int, string, string, int, int, Item”. And, the line calling the constructor only has five parameters. Make sure your Quest class matches the one from lesson 10.1 (which you can also see here: Quest.cs).

      Please tell me if that does not fix the error.

  5. Johan
    Johan January 5, 2017

    Hi Scott!

    I manage to solve it, where i added the 6th parameter, it tooked a while but now it’s working.
    I tested the code and found that the it’s not possible to use the weapon, will continue the troubleshooting.

    It was relatively easy until the copy/paste of world.cs, lot’s of code there and lots of errors since i couldn’t find all the information/code needed in the videos.

    I’m improving my troubleshooting skills though.

    Thanks for the quick reply

    Sincerely/ Johan

  6. Johan
    Johan January 5, 2017

    I missed some code 😉

    Solved.

    • Scott Lilly
      Scott Lilly January 8, 2017

      I didn’t see any obvious errors in that file.

      What problem/error do you see when you try to run your program?

  7. Josh
    Josh April 6, 2017

    Your Location objects don’t have any methods/properties which allow linking the locations together. ie. home.LocationToNorth. Each of these entries throw an error, which is what he might be talking about.

    • Scott Lilly
      Scott Lilly April 11, 2017

      Hi Josh,

      I’m sorry it took a while to respond – I’ve been on vacation.

      Are you seeing errors on the lines where we set the LocationToNorth (etc.) properties? If so, please let me know what the complete error messages says?

      The previous commenter had some other problems (I think it was in the solution files) that were causing their errors.

      • Ross
        Ross July 11, 2017

        ‘engine.Location’ does not contain a definition for ‘LocationToNorth’ and no extension method ‘LocationToNorth’ accepting a first argument of type ‘engine.Location’ could be found (are you missing a using directive or an assembly reference?) (CS1061)

        This is the error that is given. I also currently don’t have any methods for Location for LocationToNorth?

        Below is my Location code:

        public Location(int id, string name, string description,
        Item itemRequiredToEnter = null, Quest questAvaiableHere = null, Monster monsterHere = null) {

        ID = id;
        Name = name;
        Description = description;
        ItemRequiredToEnter = itemRequiredToEnter;
        QuestAvailableHere = questAvaiableHere;
        MonsterLivingHere = monsterHere;

        }

        • Ross
          Ross July 11, 2017

          To fix the problem I added in the following into the Location.cs file…

          public Location LocationToNorth { get; set;}
          public Location LocationToSouth { get; set;}
          public Location LocationToWest { get; set;}
          public Location LocationToEast { get; set;}

          Not sure if this is an appropriate solution.

    • NTWright
      NTWright April 13, 2017

      I was also having this problem, but I have been naming things differently (on purpose so I can see how the errors effect other parts (I find it easier to learn from errors)) So if I had to guess, it is a naming problem.

      • Scott Lilly
        Scott Lilly April 14, 2017

        If you are seeing the error message “Cannot implicitly convert Engine.Item to Int”, check the datatype of the RewardItem property in the Quest class – to make sure it is “Item”, and not “int”.

        If you are getting other error messages, and you cannot fix them, please let me know what they are.

  8. Jonny
    Jonny April 8, 2017

    clearAlchemistGarden.RewardItem = ItemByID(ITEM_ID_HEALING_POTION);
    clearFarmersField.RewardItem = ItemByID(ITEM_ID_ADVENTURER_PASS);
    –> “Cannot implicitly convert Engine.Item to Int”

    Is this normal? I used Visual Studio 2017

    Needed to change that to:
    clearAlchemistGarden.RewardItem = Convert.ToInt32(ItemByID(ITEM_ID_HEALING_POTION));
    clearFarmersField.RewardItem = Convert.ToInt32(ItemByID(ITEM_ID_ADVENTURER_PASS));

    • Scott Lilly
      Scott Lilly April 11, 2017

      Hi Jonny,

      I’m sorry I couldn’t answer sooner. I just got back from vacation.

      Check your Quest class, and make sure the datatype for the RewardItem property is “Item”, and not “int”. That property should look like this:

      public Item RewardItem { get; set; }

      Please let me know if that doesn’t fix the errors.

      • Jonny
        Jonny April 27, 2017

        Hi Scott Lilly,
        I’m sorry for my delayed answer, I’ve had a lot to work on this past 6 weeks or so.

        But nevermind that; yes, that unfortunate typo was the problem, I don’t know why I didn’t spot that earlier.

        Thanks for the help.

  9. Auke Keijser
    Auke Keijser June 5, 2017

    Hi Scott,

    I get about nine erros in my World, Player and Monster class all stating the following:
    Error 1 Inconsistent accessibility: field type ‘System.Collections.Generic.List’ is less accessible than field ‘Engine.World.Items’

    What am I doing wrong?

    • Scott Lilly
      Scott Lilly June 5, 2017

      Check the World, Player, and Monster classes. Make sure the classes are declared as “public” (for example, Player.cs should have “public class Player”). Also, check the properties in those classes, (and probably Location, Item, etc.), to make sure they are declared as public, and their properties are public.

      If you still have errors after checking those, please tell me here.

  10. HungNguyen
    HungNguyen August 6, 2017

    Hello Scott

    I problem with this line of code : if(location.ID ==id)

    it said “Location.ID” is inaccessible due to protection level

    How do I fix it

    Your tutorial is great

    Thank you for reading

    • Scott Lilly
      Scott Lilly August 6, 2017

      Hello,

      That message means the “scope/visibility” of the ID property is not set high enough for the other class to see it. Look in the Location class, and ensure the ID property is defined like this (with the “public”):

      public int ID { get; set; }

      Please tell me if that does not fix the problem.

  11. Arcosta
    Arcosta August 15, 2017

    Hi Scott! Thank you so much for this tutorial, I’m learning lots! I’m just a bit flabbergasted by the huge jump from the previous lesson to this one. There’s so much happening here compared to past lessons. Just wanted to say that. Thanks again!

    • Scott Lilly
      Scott Lilly August 15, 2017

      You’re welcome! Static classes (and methods) do take a “mindset shift”. When I first learned about them, it took me a while to really understand them. But, they are important to learn. You might want to look for other guides on static classes. Sometimes, it helps to hear the idea a few different ones – one of them might be the one that makes you fully understand.

  12. Johanna
    Johanna September 6, 2017

    Hi! I have a problem in world.cs. There is a QuestCompletionItems variable that is said to come from quest.cs but you have not metioned it anywhere in the preavious lessons.

  13. Johanna
    Johanna September 7, 2017

    Hi Scott.
    Totally missed it. Thanks, now everything works as it should. Thank you so much for this fun tutorial.

    • Scott Lilly
      Scott Lilly September 7, 2017

      You’re welcome. I updated the lesson last night, to display the complete code for the modified classes – to make it more noticeable.

  14. Domenic
    Domenic September 11, 2017

    Hi Scott,

    I have an error in the “Monster.Add” part in the world class.
    It says, that the Monster class doesn’t contain a definition for Add.

    Do you know how I can fix this?

    • Scott Lilly
      Scott Lilly September 11, 2017

      Is the error on lines 79 through 81? If so, those lines need to be “_monsters.Add”, to add to the _monsters variable defined on line 9.

      If that is not the source of the error, please let me know.

  15. Taryn
    Taryn October 15, 2017

    Hi Scott,

    I’ve been having trouble with code related to the Monster class but I’m not really sure what the problem is. Here are the errors that are showing up

    1. Inconsistent accessibility: property type ‘Monster’ is less accessible than property ‘Location.MonsterLivingHere’ Engine C:\Users\Taryn\Documents\Visual Studio 2015\Projects\SuperAdventure\Engine\Location.cs

    2. Inconsistent accessibility: parameter type ‘Monster’ is less accessible than method ‘Location.Location(int, string, string, Item, Quest, Monster)’ Engine C:\Users\Taryn\Documents\Visual Studio 2015\Projects\SuperAdventure\Engine\Location.cs

    3. Inconsistent accessibility: field type ‘List’ is less accessible than field ‘World.Monsters’ Engine C:\Users\Taryn\Documents\Visual Studio 2015\Projects\SuperAdventure\Engine\World.cs

    4. Inconsistent accessibility: return type ‘Monster’ is less accessible than method ‘World.MonsterByID(int)’ Engine C:\Users\Taryn\Documents\Visual Studio 2015\Projects\SuperAdventure\Engine\World.cs

    I’m really new to programming, especially in C#, so I don’t understand what the errors mean. If you could help, I would really appreciate it.

    • Scott Lilly
      Scott Lilly October 15, 2017

      Hi Taryn,

      Those errors are saying that the “scope” your Monster class is lower than it needs to be.

      The scope is the visibility of a class – what other parts of the program can see the class (or property, or function). Check your Monster class, and see if it says “public class Monster”. It probably only says “class Monster”. Because the Location’s MonsterHere property is public, then the class must also be public – the property cannot be more visible than the class it uses for its datatype.

      Please tell me if that does not fix the errors.

    • Taryn
      Taryn October 16, 2017

      Nevermind I was able to fix these errors.

      Sorry for any inconvenience

  16. Mahesh Babu
    Mahesh Babu November 16, 2017

    Hi Scott,

    The tutorial is awesome.

    in my world.cs class
    “rat.LootTable.Add(new LootItem(ItemByID(ITEM_ID_RAT_TAIL), 75, false));”

    showing error like Engine.LootItem does not contain a constructor that takes 3 arguments

    and

    clearAlchemistGarden.QuestCompletionItems.Add(new QuestCompletionItem(ItemByID(ITEM_ID_RAT_TAIL), 3));

    showing error like Engine.QuestCompletionItemdoes not contain a constructor that takes 2 arguments

    please help me

    • Scott Lilly
      Scott Lilly November 16, 2017

      Thank you Mahesh,

      Check your LootItem.cs and QuestCompletion.cs classes, to ensure they are the same as the classes in Lesson 10.1.

      Please tell me if that does not help you fix the errors.

      • Mahesh Babu
        Mahesh Babu November 16, 2017

        thanks Scott
        I solved my problem

  17. Koro
    Koro January 14, 2018

    Hey Scott,

    I have another question.
    To figure out what lists do, i tried to recreate a simple version of your world.cs page.

    basicaly i tried to recreate a list in another class without using the list commands
    (kinda like a reverse engeneering)

    so i made a class, a constructor and the used the constructor in a couple of places to
    make:

    ClassName variable1 = new ClassName(id, “random string”);
    ClassName variable2 = new ClassName(id, “random string”);
    ClassName variable3 = new ClassName(id, “random string”);
    ClassName variable4 = new ClassName(id, “random string”);

    this didn’t seemed to work. the 4 objects don’t seem to excist.
    from what i understand i was ‘initializing’ the objects in the wrong ‘scope’.
    or in my terms : they didn’t excist in the place where i readed them (i was reading by buttonclick).

    Now my question. Is that what a static class does? -> initialising objects so they excist and can be reffered to all the time?

    and is it even possible to retrieve object information like that without using the ‘foreach’ method and lists?

    it seems that i was doing something wrong by design or the syntax is just real hard.
    object.field doesnt seem to work outside the scope of the buttonclick.

    ps. I hope any of this makes sense 🙂

    • Koro
      Koro January 14, 2018

      edit last sentence
      object.field doesnt seem to work when the objects are initialised outside the scope of the buttonclick

    • Scott Lilly
      Scott Lilly January 16, 2018

      Hi Koro,

      A static class is one that always exists, and does not need to be instantiated (it cannot be instantiated). So, it is a place you can have functions and objects that can be used every place in the program.

      I would need to see the code you wrote to know exactly what is happening. But, I can make some guesses. If your four lines where you declare the variables and instantiate them are inside a function, then their scope is for that function only. They only exist within that function, and can only be seen/used inside the function. In the World class, notice that “_items” (and the other list objects) are outside the function, but inside the class. So, their scope is the class. We populate them from inside a function, but they are declared outside the function. So, the scope of those variables is greater than the function. Their scope is the class.

      Does that make it clearer?

      • Koro
        Koro January 17, 2018

        Yes ty.

        its a bid counterintuitive how c# works with its OOP design, but its stating to make more sense after a lot of trial and error.

        Even though your tutorial is the best i have seen so far.
        Learning c# without any pre programming knowledge is hard 🙂

        • Scott Lilly
          Scott Lilly January 17, 2018

          You’re welcome.

          Learning programming is similar to learning how to ride a bike. At the beginning, it does not feel “natural”. But, the more you practice, the easier it gets. 🙂

  18. Mark
    Mark January 18, 2018

    Hello Scott,

    Is there a way where I can just loop all the new created weapon.

    Ex. Weapon katar=new Weapon(….);

    Loop
    {
    WeaponList.Add(Object weapon)
    }

    • Scott Lilly
      Scott Lilly January 19, 2018

      We could do that if we got the data for the weapons from a database or file. With that, we would read all the records/lines from the database/file, loop through those records/lines, and create weapons from that data.

      Does that make sense?

Leave a Reply

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