A First Look, Part 1

From RPG Creation Kit
Revision as of 19:56, 14 February 2022 by Silvematt (talk | contribs) (Silvematt moved page A First Look to A First Look, Part 1)
Jump to navigation Jump to search

In this tutorial we will deeply examine a quest from the Demo, which is "Every Dead Man's Nightmare", if you have not played this quest, do it before proceeding with the tutorial. This is a long article where most of the elements of the RCK are used and explained in depth, or at least mentioned, so make sure you have plenty of time before going forward.

The Quest goes this way:


The Player arrives to the North-East village and notices a board with some notes hanged on it. He gets near and examine them, the note is written by "Mother Nebivia", the priestess who runs the Curch, apparently there is a man who is digging graves and stealing the goods buried with the dead people at the cementary. The Player picks up the note, and the Quest starts. The first objective is to speak to Mother Nebivia, which will give the Player more details about what is going on, then the Player is sent to check the cementary.

When he arrives, he will see the Thief digging a grave. When the player will get closer, the thief will stop digging and talk to the player. Here the player can decide what to do, the quest can end in three ways:

  • The player accepts a bribe form the Thief.
  • The player kills the Thief.
  • The player convinces the Thief to stop doing what he's doing.

If the Player accepts the bribe, the quest ends straight away.

If the player kills or convince the thief to go away, he will have to report the news to Mother Nebivia, that will give him a reward and end the quest.


This quest utilizes most of the features that the RCK has to offer, that is why I've picked it as the quest to deeply analyze although it is not the easiest quest to make, because if you understand how this quest is made, you'll understand how the RPG Creation Kit really works and how every other quests in the Demo are made.

The Quest "Every Dead Man's Nightmare" has the ID: "SQ_EveryDeadMansNightmare" and is accessible to be viewed from the Rck Object Viewer.

Make sure to follow those two links to learn what a Quest is, how is it composed and how to open a quest with the Quest Editor before proceeding.

Quest Settings

Open the Quest "Every Dead Man's Nightmare" in the Quest Editor and take a look at the content of the "Quests" tab.

There are three important things that you should notice are:

  • The ID of the Quest is "SQ_EveryDeadMansNightmare", so that is how we will reference to this quest.
  • The First Stage Is Default Stage, so when this quest is firstly added, the first stage in the list is the Stage that will be set as the Current Quest Stage.
  • The Quest uses a Quest Script called "EveryDeadMansNightmareQuestScript".


Keep those things in mind as they are meaningful in the next steps.

Starting the Quest

At this point the Current Stage of the quest is 0, since the quest never started.

The way the quest starts for the Player, as we said, is by picking up a note from the board. This note is a Book Item, a type of Item that represents a Book or a Note readable by the Player. What the Player sees on the board, is the Item In World of the "QI_NoteLookingForWork001" item, accessible from the Rck Object Viewer.

Open up the "QI_NoteLookingForWork001" in the Item Editor and you will notice few things:

  • The Book Text says exactly what is displayed in game.
  • You'll see the 3D model of the Item In World.
  • You'll notice that it has an Item Script assigned.


Out of every settings, the only one that could add the quest is obviously the Item Script.

Now, if you're not a programmer and you don't know how to code, don't worry, you're totally fine. Indeed, what happens here fundamentally is Scripting. You will not have to learn how to code, but you'll just have to use pre-made functions. Knowing how Scripting works is important, as it is a way to make things works and progress and as some things can be done only through Scripting. I'll make sure to explain it as the best as I can.

The Item Script is a piece of code that runs when certain events regarding items occurs, such as when the Item is added into an inventory, or when the Item is equipped, dropped, took or deposited from/in a Looting Point.

Which is exactly what we are looking for, as we know that we want to start the Quest as soon as the note is added in the Player Inventory.

Look up for the Item Script "HangingNote001ItemScript" inside the project and open it into Visual Studio, or whatever editor you've installed:

   public class HangingNote001ItemScript : ItemScript

   {
       public override void OnAdd(Inventory inventory)

       {
           base.OnAdd(inventory);

           if(inventory == Inventory.PlayerInventory && RCKFunctions.GetStage("SQ_EveryDeadMansNightmare") == 0)
               RCKFunctions.AddQuest("SQ_EveryDeadMansNightmare");
       }
   }

Don't you dare getting scared, this code is actually very slim and simple.

Whenever you see "public override" it means that we are defining the behaviour of what needs to occur upon a certain action, this action is written at the immediate right, in this case it's the "OnAdd". The "inventory" represents the Inventory that just received this Item.

Let's look at the content of the function, you can ignore the base.OnAdd(inventory); and focus on what is written below, the two lines that interests us.

The first one is a condition:

if(inventory == Inventory.PlayerInventory && RCKFunctions.GetStage("SQ_EveryDeadMansNightmare") == 0)

Means "if the inventory that received this item is the inventory of the player (so if it was the player receiving the item) AND at the same time (&&) the current stage of the quest with ID 'SQ_EveryDeadMansNightmare' is equal to 0 (means the quest didn't started yet, nor it was ever completed)" execute the line below:

RCKFunctions.AddQuest("SQ_EveryDeadMansNightmare");

That means: "Add the quest with the ID 'SQ_EveryDeadMansNightmare'".

And with just that we're done, as soon as the player will pickup the note, the quest will start, the interface will be updated, as well the journal. The Current Stage of the quest will have the value of 10 and the Player will be able to continue with the quest.

If you're wondering what RCKFunctions is, it's just a static class that contains a lot of pre-made functions just as these two we've seen above (GetStage and AddQuest), we'll get to it later, you will use it a lot.

Stage 10

The Stage 10, if opened and viewed in the Quest Editor, does not have any particular setting, but the description "Speak to Mother Nebivia at the Curch".

We can easily deduce that to progress with this quest, we will need to make use of Dialogues.

Before going forward, focus on the Cell View, select as the Worldspace "Virrihael" and open the cell with ID "Virrihael(2,2)" by double clicking on the corresponding button. You will see in the Scene View that you are in the village, move around and notice on the board at the entrance the Item In World of the note we've analyzed before.

The AI Actor of Mother Nebivia outside the Curch in the cell "Virrihael(2,2)".

Now move near the Curch and you will notice that Mother Nebivia is placed there.

Actually, an instance of her is placed there, because every AI Actor has a corresponding prefab that lives inside the project, however, the same AI Actor prefab should be only placed in the world or instantiated once.

Click on her and take a look at the Inspector, focus on the "Rck AI" component. For the Stage 10, we are interested in her dialogue components, so click on the "Dialogue" tab and the Inspector will show all the relevant dialogue's information.

We want to analyze her Current Dialogue Graph, which is the Dialogue that will run when the player speaks to her. Double click on the Current Dialogue Graph reference, and the Dialogue will open in the Node-Editor Window.


From there, I suggest you read the Dialogue page before proceeding and get a rough idea on how dialogues are made and which are their components.


Before analyzing it, let's say what we want and how talking to Mother Nebivia should work:

  1. Mother Nebivia greets the player with a random greet phrase.
  2. The Player is prompted to ask or say something. If he is in Stage 10 with the quest "Every Dead Man's Nightmare", he should be able to ask for more information about the Thief. Otherwise if he didn't picked up the note, that dialogue option should not appear.
  3. The player can ask about the Church.
  4. The player can leave the conversation.


The first thing that you should notice in the dialogue is the Entry Node, this is where every Dialogue starts.

To achieve the point 1. of our dialogue, we use a Random Node, which will select a random end point between the list and redirect the dialogue to one of the three NPC Dialogue Lines, that will allow Mother Nebivia to greet us.

The point 2. has been explained with a condition, in fact, we said that we only want to be able to ask about the Thief if the Current Quest Stage is 10. To achieve that we need to use a Conditions Node, where the conditions are:

  • Stage of the quest "Every Dead Man's Nightmare" > 0 (means the quest has started).
  • Stage of the quest "Every Dead Man's Nightmare" <= 10 (means we never went further of Stage 10).

If you click on the "Configure Conditions" button in the Conditions Node, you will see the exactly same conditions implemented inside the window.

The Conditions Node has two ends, "Result True" and "Result False" which will redirect the dialogue in base of the result of the processing of the conditions. If the player picked up the note and never went further than Stage 10, the dialogue will continue on the "Result True" end, otherwise the dialogue will continue on the "Result False" end.

At both ends you'll find a Player Questions node, with the questions the player can ask. The response to each question will redirect the dialogue to the connected node. The two Player Question nodes are almost identical, but one of them, the one that plays if the Conditions are met, has an extra question that says "About that note on the board...", while the others all redirects to the same NPC Dialogue Lines.

And that's pretty much it, notice how the dialogue flows in the other cases (when the other questions are asked) and you will find the remeaning 3. and 4. points of our dialogue.

To progress with the quest, we need to ask "About that note on the board..." that will trigger a sequence on NPC Dialogue Lines where the last one will have some special settings that will allow the quest to proceed.

The last NPC Dialogue Line of Mother Nebivia dialogue, this is the element that will make the quest progress from Stage 10 to Stage 20.

Let's analyze the last NPC Dialogue Line.

Click on Show/Hide to reveal hidden properties and settings, we are interested in the Events this node will execute. Events and Consequences are shortcuts that you will use to make things happen inside the game. They can partially replace the needing of using Scripting, indeed, we could have started the quest with Events in the first place instead of using the Item Script, but for the sake of learning and because I think it's more well-organized this way, Scripting was used.

Events helps you have 3 fundamentals things:

  • Quest Dealers: adds new quests.
  • Quest Updaters: sets new stages and completes existing ones.
  • Consequences: applies various consequences.


We need to progress with the quest, so we need to use Quest Updaters.

We'll use two of them, one for completing the Stage 10 and another one for setting the Stage to 20.

With this we are done with this Stage, as soon as the NPC will speak this line the Quest will progress, the Current Quest Stage will be 20, the dialogue will end (because of the After Line) and the player will be able to progress with the quest.

Notice that if you speak to Mother Nebivia again, the Condition Nodes will always return false, because the Current Quest Stage is 20, so it's greater than 10 and it doesn't match the conditions we've set anymore, neither it will ever do again.

Stage 20, Part I

Open the Quest in the Quest Editor and take a look at the Stage 20. You'll notice that it has a Quest Stage Script assigned. The quest stage scripts works very similiar to the Item Script we'e analyzed before, the only difference is that it gets executed as soon as we reach the Stage its set to.

So this Quest Stage Script will be executed as soon as we reach the Quest Stage 20, which we already did by speaking to Mother Nebivia. Let's open the script, search for "EveryDeadMansNightmareStage20Script" in your project, open it up and take a look:

public class EveryDeadMansNightmareStage20Script : QuestStageScript
{
  private void Start()
  {
     // Your code here
     RCKFunctions.SpawnAIInCell("ThiefOfTheDead001", "Virrihael(2,0)", new Vector3(282f, 0.1f, 13.52f), Quaternion.Euler(0, 90, 0));

            // Use this line to destroy the script if it is not longer needed.
            Destroy(this);
   }
}

This code is based on the call of a single function named "SpawnAIInCell", which does exactly what you may have guessed. Inside the parentheses you are asked to give more information about who you want to spawn, in which cell, at which position and at which rotation.

So as soon as the Stage 20 starts, this line of code will run and it will spawn the AI with ID "ThiefOfTheDead001", inside the cell "Virrihael(2,0)", at the position (282f, 0.1f, 13.52f) with a rotation of (0, 90, 0).

The Destroy(this) is called to destroy the script as it is no longer needed once it has executed the line above.

Now if in the game you'll go to the cementary, you will see that the Thief has spawned and he will start digging a grave, while if you hadn't spoken with Mother Nebivia and went to the cementary, he wouldn't have been there. This happens because as we've seen the Thief is spawned by the Quest Stage Script of the Stage 20 of our quest.

Cell "Virrihael(2,0)" loaded in the Scene View. This is where the quests progresses on the Stage 20.

Open the Cell "Virrihael(2,0)" with the Cell View, you will be brought to the cementary where the quest continues. If you create a cube inside the scene and set its position as (282f, 0.1f, 13.52f) you will exactly see where the Thief will be spawned.

If you focus on the blue dummy model, you'll see that it really looks like he's digging the grave, you're in front of an NPC Action Point, which is essentialy a point where an NPC can play an animation, in this case the animation of digging a grave. The blue dummy model will preview in the Editor where the animation will start (and where it will loop).

Perfect, we've understood how the AI gets spawned in the Cell, and that by using the NPC Action Point that is present there he can look like he's digging a grave, but where is exactly the Thief?

Every NPC in the game, and every NPC you'll create are prefabs accessible and editable by the Rck AI Editor. Open the Rck AI Editor by clicking from the top-menu "RPG Creation Kit -> RckAI Editor".

The Window will open, and you can notice on the left a long list of IDs, which are the IDs of every NPC present in the demo, you can scroll down or use the searchbar to find the NPC we're looking for: ThiefOfTheDead001.

If you click on it, in the center of the Window a configuration menu will appear, where you'll be able to customize your NPCs, set their initial Dialogues, Inventory, Behaviour and Factions. Take a look at every tab and get an idea on how things are setup.

Now focus on the "Behaviour" tab, in this tab we will assign the default Behaviour of the NPC, that will determine how the NPC will act as soon as he's spawned. To achieve the Purpose Behaviour (the Behaviour the NPC has when he's not in combat) we've explained at the beginning of this article, the Behaviour "S_BTree TheThiefOfTheDeadDefaultBehaviour" was created - the S_ in the name stands for "Specific". In fact, we've described a pretty unique Behaviour that no one will ever use but the Thief, so it made a lot of sense creating a specific Behaviour opposed as a non-specific behaviour like "Follower Dynamic" that is used by a variety of NPC throughout the game.

The Combat Behaviour on the other hand describes how the AI will fight an enemy, in the Demo every NPC utilize the same Combat Behaviour "Full Combat".

Behaviours are probably the part that requires the most amount of testing and tweaking to get it right, and they can be a little bit intimidating at first, especially if you want to create your own New Behaviours. But don't worry, using pre-made ones, as we'll do in this and in the next tutorials, is as easy as assigning a reference and most of the times you'll find yourself using the same pre-made Behaviours over and over. Mother Nebivia herself, if you care to check, uses a generic "EmptyState" Behaviour that allows her to stand still on her location.

Back to our specifc Behaviour, what it really does is to make the NPC use the NPC Action Point as soon as he spawns and wait until the Player gets near. When the Player gets near, the NPC will stop using the Action Point (he will put the shovel away) and his Behaviour is changed. From the "S_BTree TheThiefOfTheDeadDefaultBehaviour" he will use "S_BTree TheThiefOfTheDeadFollowPlayerBehaviour", which will do nothing more than make the NPC follow the Player and force the start of the dialogue with him as soon as he gets really close.

If you're wondering what physically changed the Behaviour from "Default" to "FollowPlayer", in this case it was a Node inside the DefaultBehaviour, we'll take a look at that soon, just keep in mind that you can set and switch Behaviours for NPCs from anywhere, scripts, events, dialogues, and so on and so forth.

So we've seen how an NPC utilizes Behaviours, how they allow us to make the NPCs do what we want and how they can be switched to create a more complex set of actions.

If you made it through until here, congraturations, we've looked at a lot of things that are the cornerstone of the creation of your RPG game, you may take a small break now before going on. If you're confused and have a lot of unresolved questions, don't worry now, you just got started, give yourself some time, keep going with the tutorials and hopefully things will clarify as you progress.

This tutorial continues with A First Look, Part 2.

Stage 20, Part II

We've left Part I while being in Stage 20, with the Thief approaching and forcing us to dialogue with him, and we've seen that this happened because of the Thief's Behaviour.

We are at the highlight of the quest, from now on the next stage will be determined by the Player's actions. This reveals the fact that Quest Stages are not always to be executed in order, some of them can be skipped or ignored, and you are free to set and branch you quests as you want.

The conversation the Player will have with the Thief is the Current Dialogue the Thief has, and it is called "TheThiefOfTheDeadDefaultDialogue". To view it you can search it in the Rck Object Viewer or in the Rck AI Editor (Behaviour tab) while having "TheThiefOfTheDead001" selected.

Open it up in the Node Editor and let's take a look.

You should be able to get an idea on what happens, the Dialogue starts with the Entry Node that redirects to an NPC Dialogue Line, the NPC speaks its line and then the player is prompted to say something (After Line = Player Questions).

The quest branches from there, in base of what the player will pick the quest can end in three ways, as we've seen in the beginning of this article. We will analyze every possible outcome that will let the player complete the quest.

1. Stage 30 - Player Kills the Thief

The Player can decide to kill the Thief by selecting the dialogue option "[Attack] Your crimes are unforgivable". Find the option in the Dialogue, and let's analyze what happens next. The end of the question is connected to a NPC Dialogue Line Node, so the Thief will speak a line "This is not your grave, but you are welcome in it". What should happen next, is that the Thief will attack the player, and this is achived via Events in the configuration of the node. Click on "Show/Hide" to reveal the hidden properties and settings, then open the Events.

You will see that there is a Consequence of type "RckAI Add In Faction" which pretty much explains itself, it allows to set an NPC to a determined Faction. The Consequence is configured to Add the NPC with ID "ThiefOfTheDead001" to the Faction with ID "AgainstPlayer".

Setting an NPC to the "AgainstPlayer" Faction will make the NPC attack the Player at sight, which is exactly what we're looking for.

The Dialogue continues with a special Node, which is the Dialogue AI Invoke, this node allows you to call AI Functions from within the Dialogue, the AI that will be changed is obviously the AI that is talking to the Player. Just as we've changed the Behaviour the last time (going from DefaultBehaviour to FollowPlayer) here we are switching Behavior again, this time to the EmptyStatePurpose that will make the NPC standing still. We want him to stand still because as soon as he detects the Player, he switch in Combat and will attack him, because we've set him in the "AgainstPlayer" Faction.

The Dialogue ends with an End Node, which has two Quest Updaters that lets the Player complete the Stage 20 and set the Current Quest Stage to 30.

The Stage 30, if looked in the Quest Editor, doesn't have anything special but the description.

So what happens now is that the Current Quest Stage is 30, the Player has as the current objective "Kill the looter", and the Thief NPC is attacking the Player.

Perfect, now the last thing that we need is to update the quest when the Thief dies.

To do that, we utilize the Quest Script we've seen in the Quest Editor.

A Quest Script is very similiar to the Quest Stage Script we've seen and used before, but it has one big difference. A Quest Stage Script is designed to execute some lines of code and then get destroyed, while the Quest Script runs periodically while a quest is active.

That means that throughout the whole mission, and still right now, every X seconds the Quest Script assigned to this quest was being executed.

The Quest Scripts are useful in the occasion when you don't really know when something needs to happen, while with the case of the Quest Stage Scripts we always knew when something had to happen (we knew for example that the Thief had to spawn after speaking to Mother Nebivia).

So a Quest Script is perfect for our case, since we don't really know at which time the Player will kill the Thief, or if he will at all.

The script we're talking about is "EveryDeadMansNightmareQuestScript" and it is fundamentally very simple, altrough it is a little bit longer. If you've understood the previous Scripts, you shold have no problem getting this too, and once you got it, we're done.

Open the script and let's analyze it.

The first thing that you'll notice is that it utilizes four variables:

bool doonce = false;
bool doonce1 = false;
bool doonce2 = false;

RckAI thiefofthedead = null;

"doonce(1,2)" are booleans, they are used to ensure that some things only happen once, we will set those variables to true as soon as we execute the lines we want to be executed only once.

"thiefoftheidead" instead, is a reference to the NPC. It let us access to every aspect of the NPC, in our case we will use it to check if the NPC died.

Quest Scripts always have at least two functions:

public void Start()

And

public override void CustomUpdate()

Let's analyze both of them. The first one will allow you to set the value of the questScriptExecutionDelay, which is the X amount of seconds that have to pass for the "CustomUpdate" function to be executed. Not only, the Start calls the function "RunQuestScript()" that will make the script run.

public void Start()
{
     quest.questScriptExecutionDelay = 1f; // CustomUpdate runs every 1 second.
     RunQuestScript(); // Starts the CustomUpdate
}

Let's take a look at the CustomUpdate(): This may be a intimidating at first, but it's very simple as well. The first two lines:

if (thiefofthedead == null)
   CellInformation.TryToGetAI("ThiefOfTheDead001", out thiefofthedead);

Says: if the reference of the NPC is null, try to get it. The code will not go forward this point reference is found and set. The reference will be available to the Quest Script when the Thief NPC will be loaded in the scenes, at the next call of the CustomUpdate() the function "TryToGetAI" will finally get the reference. This is the standard way to get NPC references and it is used widely throughout the whole Demo. The "else" block runs only if the reference is set, for now ignore the first and last blocks and focus at the one at the center:

else if(quest.currentQuestStage == 30 && !thiefofthedead.isAlive && !doonce1)
{
   // Progress with quest
   RCKFunctions.CompleteQuestStage(quest.questID, 40);
   RCKFunctions.CompleteQuestStage(quest.questID, 30);

   doonce1 = true;
}