Lesson 06.2: Using Quests in the Game

In this lesson, we will add quests to locations, give quests to the player (when they move to a location with a quest), and display the player’s quests on the screen.

The changes will be similar to what we did to add an inventory to the Player class, and display it on a tab in the UI.




Step 1: Open Engine\Models\Location.cs

We’ll add a new List<Quest> property, to hold quests available at the Location.

I’m making it a list property, so we can have multiple quests available at a location. In the future, we may create quest “chains”, where the player needs to complete one quest, before they can receive the next quest in the “chain”.







Step 2: Open Engine\WorldFactory.cs

After we create the Herbalist’s Hut location (position 0, 1), we will add the “Clear the Herb Garden” quest to its new QuestsAvailableHere property.

newWorld.LocationAt(0, 1) returns a Location object, which has its QuestsAvailableHere property. We can directly add the quest to this location by calling the code in this order.





Step 3: Create a new class Engine\Models\QuestStatus.cs

This is like the ItemQuantity class – except, instead of tracking the quantity of an item, we will track the completion status of a quest.

When the player receives a quest, we will create a new QuestStatus object, and set the IsCompleted status to “false”. Later, when the player completes the quest, we will set IsCompleted to “true”.




Step 4: Open Engine\Models\Player.cs

Like the Player Inventory property, we will create a new Quests property. This is an ObservableCollection<QuestStatus>, so it can automatically update the UI when the Player receives a new quest, or completes one of their existing quests.





Step 5: Open Engine\ViewModels\GameSession.cs

This class handles player movement. So, we will modify it to check if there is a new quest available, when the player moves to a new location.

We need to add “using System.Linq;”, so we can use LINQ to search through the CurrentPlayer’s Quests list – to ensure we don’t give the player a quest they already have (in the GivePlayerQuestsAtLocation function).

We also need to update the “set” for the CurrentLocation property. Now, when the player moves to a new location, and CurrentLocation is updated, we will call GivePlayerQuestsAtLocation the new function at the end of the GaneSession.cs.





Step 6: Open QPFUI\MainWindow.xaml

Finally, we will add another TabItem, to display the player’s quest, and its completion status.

This is like the Inventory tab. We bind it to the Player’s Quests property and configure the columns to display.

Notice that the first column is binding to PlayerQuest.Name. This is because we are binding to a list of QuestStatus objects. The QuestStatus.PlayerQuest property is a Quest object, which has a Name property. So, we are displaying a property of a property.

The new code is the TabItem for the Quests, at lines 121 to 134.





Return to main page

13 thoughts on “Lesson 06.2: Using Quests in the Game

  1. Scott,

    I am interested in following along with this project. Is there a lesson where I can download the source code and start at a mid-point? Or, is it better to just start from the beginning. The reason I ask is I don’t have a lot of time to get started. I would like to be caught up so I can do each lesson as you release them.



        1. I am all caught up! Your tutorials are very clear and straight forward. I am going to make a copy of the solution to tinker with and keep one for when you come out with new lessons.

          Thanks again!

  2. Hi Scott,

    I m using visual studio 2013
    My i know how to convert this

    public List QuestsAvailableHere { get; set; } = new List(); (C#7.0)

    to 2013 version?


    1. Hi Marcus,

      With earlier versions of C#, you will need to set the property’s initial value inside the constructor, instead of on the same line where you declare it.

      So, you would declare the property with:
      public List QuestsAvailableHere { get; set; }

      Then, in the constructor, add this line:
      QuestsAvailableHere = new List();

      Please tell me if that does not work, or if you have any questions.

      1. HI Scott ,
        Sorry for late reply.The sample is working.

        My Code
        public List QuestsAvailableHere { get; set; }
        public Location()
        QuestsAvailableHere = new List();


        Thanks a lot.


  3. Hi Scott, first post for me on your site. I wanted to say how much I have been enjoying your tutorial and how I am looking forward to taking what is made here further myself. A quick question could you explain line 116 of the GameSession.cs a little more

    if(!CurrentPlayer.Quests.Any(q => q.PlayerQuest.ID == quest.ID))

    I understand most of it my only question is the q part of it (q => q.PlayerQuest.ID) what is the q stand for I and why do we need it? Sorry this is probably a really stupid question.

    1. Hi Benjamin,

      The “q” is used as a variable to hold each object in the collection.

      In the “Any” method, we want to see if any of the Quest objects in CurrentPlayer.Quests have an ID that matches the ID of the Quest object in the “quest” variable. To do that comparison, we’re going to put each Quest object (from “CurrentPlayer.Quests”) into the “q” variable, and perform the comparison “q.PlayerQuest.ID == quest.ID”.

      If we didn’t use LINQ, we could write the code like this (I didn’t build this code, so there could be an error). Notice the “q” variable in the “foreach” line. This is basically the same “q” variable in the LINQ statement:

      bool playerHasQuest = false;
      foreach(Quest q in CurrentPlayer.Quests)
      if(q.PlayerQuest.ID == quest.ID)
      playerHasQuest = true;

      Let me know if that isn’t clear, or if you have any other questions.

  4. In line 116 of the GameSession.cs a little more

    if(!CurrentPlayer.Quests.Any(q => q.PlayerQuest.ID == quest.ID))

    What does => mean. I always thought it was “a greater than or equals” symbol. Does it mean something different in this code?

    1. The => operator is used for lambda expressions (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-operator).

      The Any() function is looking for an equation that will evaluate to “true” or “false”. It’s going to run against all the objects in the CurrentPlayer.Quests collection. For each object in the collection, it will assign it to the “q” variable (on the left side of the lambda operator), use that “q” variable in the equation on the right of the lambda operator “q.PlayerQuest.ID == quest.ID”, and determine if that object returns a true or false for that equation.

      That line of code is about the same as this (assuming I don’t make a mistake):

      bool playerHasQuestWithTheSameID = false;

      foreach(Quest q in CurrentPlayer.Quests)
      if(q.PlayerQuest.ID == quest.ID)
      playerHasQuestWithTheSameID = true;

      ... do the code inside the original "if"

      The => is also used for “expression-bodied members“, which you might use in place of a very small function.

Leave a Reply

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