This document describes the concepts of what makes up a quest in Andor’s Trail. It is aimed to be a tutorial for those that want to help create new quests in Andor’s Trail.
This area will help you learn to develop quests for Andor's Trail. Be sure that you have read the World & Lore sections to assist with tying your idea in with current story lines.
Please check the list of available NPC's before crossing your quest idea with another.
The mini-howto on making a quest for Andor’s Trail is something like this:
The above steps will be described in detail below.
The hardest part is by far to write the dialogue. Writing the dialogue is also the most interesting parts, since it allows you to customize the tone of the quest, and the characteristics of each involved NPC. It’s the story-telling part of the quest.
NPC=Non player character. For example, a quest giver.
In order to come up with an idea for a quest, there are a lot of good resources:
http://www.squid.org/rpg-random-generator
http://dicelog.com/yafnagen
http://donjon.bin.sh/name/
For this tutorial, we will assume that we want to create a quest called “You remind me of the babe, what babe?“, where the player is requested to retrieve a lost treasure map from a goblin cave. The quest will be given by an NPC named Cileth in Fallhaven (this quest is not actually present in Andor’s Trail). The player will be given a choice of whether to spare the goblin boss monster or not.
A flowchart is an excellent tool to use to help concretize the structure of the quest. It is of course not always needed, but can sometimes help a lot when planning the high-level structure of a quest, in order to not get stuck on the details too quick.
For the existing quests in Andor’s Trail, various tools have been used to create flowcharts for quests, but the tool that (at the moment) wins in ease-of-use is to create a drawing in Google Docs.
For the example quest in this tutorial, a flowchart could look something like this:
The flowchart will be an excellent help when writing the quest log, in the next section.
In the game, the text you see on the character screen, in the “Quests” tab, is called the quest log. Each quest is composed of several stages, where each stage has an assigned internal integer value. As the player progresses in a quest, their progress will be represented by which of these stages that the player has reached.
Looking at the flowchart for the quest, each box will be represented by roughly one quest stage.
As you may have noticed, the quest log is always written in the first tense, as if the player wrote the text. For example, “I saw a ..” compared to “The player saw a ..”.
Our quest with Cileth might have these quest stages:
Stage | Description |
---|---|
10 | I heard a rumor in Fallhaven about someone named Cileth that lost something very valuable. |
20 | I talked to Cileth in Fallhaven. She told me about a treasure map that she used to have, but that she lost it a few days ago, while travelling in the wilderness. |
30 | I have agreed to help Cileth find the treasure map. |
40 | Cileth believes that she might have lost the map near a cave that was filled with goblins, outside the village. She has given me directions to the cave. I should go there and search for the map inside. |
50 | Inside the goblin cave, I encountered a goblin named Olgnuur. Olgnuur told me that the goblins just want to be left alone by all the pesky humans. If I leave him alone, he will give me the map. |
60 | I have agreed to spare Olgnuur’s life. |
65 | Olgnuur has given me the map. |
70 | I have started attacking Olgnuur. I should return with the map to Cileth once Olgnuur is dead. |
80 | I have given the map back to Cileth. |
90 | Cileth rewarded me with some gold for helping her recover the map. |
In this example, notice that the player might choose to reach 60, but never 70, or vice versa.
The stage values can be anything, as long as they are positive numbers. They will be presented in the player’s quest log in order by stage value.
To implement this quest log in the game, we’ll have to write it as a quest in the Andor’s Trail Content editor: http://andors-trail.googlecode.com/git/AndorsTrailEdit/editor.html
The internal id can be anything that uniquely defines this quest, it will not be shown to the player. Notice how stage 65 and 90 also gives some exp rewards when reached. Also notice how stage 90 marks the quest as completed.
In the content editor, notice the “Export” button in the top right. The output from that is what will go into the actual game files when this quest is integrated in the game later. The export of this quest looks like this:
[id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|]; {cileth_map|You remind me of the babe, what babe?|1|{ {10|I have heard a rumor in Fallhaven about someone named Cileth that has lost something very valuable.|||} {20|I have talked to Cileth in Fallhaven. She told me about a treasure map that she used to have, but that she lost a few days ago, while travelling in the wilderness.|||} {30|I have agreed to help Cileth find the treasure map.|||} {40|Cileth believes that she might have lost the map near a cave that was filled with goblins, outside the village. She has given me directions to the cave. I should go there and search for the map inside.|||} {50|Inside the goblin cave, I encountered a goblin named Olgnuur. Olgnuur told me that the goblins just want to be left alone from all the pesky humans. If I spare his life, he will give me the map.|||} {60|I have agreed to spare Olgnuur\'s life.|||} {65|Olgnuur has given me the map.|500||} {70|I have started attacking Olgnuur. I should return with the map to Cileth once Olgnuur is dead.|||} {80|I have given the map back to Cileth.|||} {90|Cileth rewarded me with some gold for helping her recover the map.|500|1|} }|};
The example quest in this tutorial will require three unique NPCs that progress the quest. There is the NPC that will provide the rumor about Cileth having lost something, there is Cileth herself and there is the goblin boss monster Olgnuur.
Each of these NPCs can be created in the content editor:
Cileth
Olgnuur
The export of them (visible from the export button in the top right of the content editor) is as follows:
[id|iconID|name|tags|size|monsterClass|unique|faction|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|droplistID|phraseID|hasHitEffect|onHit_boostHP_Min|onHit_boostHP_Max|onHit_boostAP_Min|onHit_boostAP_Max|onHit_conditionsSource[condition|magnitude|duration|chance|]|onHit_conditionsTarget[condition|magnitude|duration|chance|]|]; {gwend|monsters_rltiles3:14|Gwend|gwend||0|||||||||||||||gwend||||||||}; {olgnuur|monsters_rltiles2:129|Olgnuur|olgnuur|1x1|0|1||69|10|5|3|140|20|2|2|13|60||olgnuur|olgnuur||||||||}; {cileth|monsters_rltiles1:68|Cileth|cileth||0|||||||||||||||cileth||||||||};
Notice that Olgnuur has combat stats, since the player might choose to fight him. Cileth, on the other hand, does not have combat stats since there will be no option to fight her.
Most fields in the monster/NPC editor should be self-explanatory, but some fields worth noting are:
Field | Description |
---|---|
Internal Id | Can be just about anything, just make it uniquely define the monster. Will not be visible to the player. Prefer short values in lower-case. Use _ instead of spaces. |
Spawngroup | This value will be used on the map where the monster or NPC is spawned, to define what types of monsters the spawn area should contain. For example, if several monsters specify their spawngroup as “goblin1”, and the map contains an area that spawns group “goblin1”, the game will randomly select one monster type from that group to spawn there. For NPCs, this value should be equal to their internal id. |
Faction | Advanced feature for quests that causes monsters to become hostile without interacting with them. Just leave it empty for now. |
Conversation Phrase ID | The id of the starting Phrase that will be shown when the player engages in dialogue with the NPC. See “Dialogue” below for more info on what a Phrase is defined as. For NPCs, prefer to name the starting phrase to the same as the NPC’s internal id. |
Droplist ID | The id of the list of things that will be dropped when the player kills the monster or NPC. See “Quest items” below for more info. |
Also note that Olgnuur has a droplist specified, but Cileth does not have one. This is again because Cileth will not be available for combat - only Olgnuur will.
The maps in Andor’s Trail are created by using Tiled as map editor. http://www.mapeditor.org/
To place these three NPCs on maps, we open the map files using Tiled, and create object areas of type “spawn” where they should be placed:
Placing gwend (the NPC that tells the rumor)
Placing Cileth:
Notice that the names of the spawn areas on the maps correspond to the values in the “spawngroup” field of the monsters that should be spawned there.
This quest will require a quest item, the map that Cileth has lost. It can be created in the content editor:
The export of this item (visible from the export button in the top right of the content editor) is as follows:
[id|iconID|name|category|displaytype|hasManualPrice|baseMarketCost|hasEquipEffect|equip_boostMaxHP|equip_boostMaxAP|equip_moveCostPenalty|equip_attackCost|equip_attackChance|equip_criticalChance|equip_criticalMultiplier|equip_attackDamage_Min|equip_attackDamage_Max|equip_blockChance|equip_damageResistance|equip_conditions[condition|magnitude|]|hasUseEffect|use_boostHP_Min|use_boostHP_Max|use_boostAP_Min|use_boostAP_Max|use_conditionsSource[condition|magnitude|duration|chance|]|hasHitEffect|hit_boostHP_Min|hit_boostHP_Max|hit_boostAP_Min|hit_boostAP_Max|hit_conditionsSource[condition|magnitude|duration|chance|]|hit_conditionsTarget[condition|magnitude|duration|chance|]|hasKillEffect|kill_boostHP_Min|kill_boostHP_Max|kill_boostAP_Min|kill_boostAP_Max|kill_conditionsSource[condition|magnitude|duration|chance|]|]; {cileth_map|items_books:9|Cileth\'s map|31|1|1|0|||||||||||||||||||||||||||||||||};
To make Olgnuur drop this particular item when he is killed, we’ll create a droplist in the content editor:
Olgnuur will drop a few more items when killed, to provide some loot for the player to collect. Notice how all of them have 100% chance of being dropped, and in particular the map itself - it could break the quest if Olgnuur could be killed but would not always drop the map. Quest items should always have 100% drop chance.
The export of this droplist is as follows:
[id|items[itemID|quantity_Min|quantity_Max|chance|]|]; {olgnuur|{ {gold|4|12|100|} {gem2|1|1|100|} {health|1|1|100|} {cileth_map|1|1|100|} {gloves1|1|1|100|} }|};
Notice how the internal id of the droplist corresponds to the field “droplist id” in the monster that we defined previously.
The conversations are always triggered by the player engaging conversation with a NPC, or the player stepping on certain tiles. As you noticed in the monster/NPC editor above, all NPCs will have a phrase ID that points to the start of the conversation of that particular monster type.
A conversation can be seen as a large state-chart of phrases that the player visits by selecting different replies. An example of a conversation tree could be like this:
Notice how the conversation flow can return to places where it has already been, and how some conversation choices can lead to more interesting stories. This is all done in Andor’s Trail by what is aptly named phrases and replies.
To create a conversation in Andor’s Trail, you don’t have to draw a flowchart like the one above - this one is only for illustrative purposes in this tutorial.
Looking at the flowchart above, let’s call each blue box that the NPC speaks a Phrase, and let’s call the text on each arrow a Reply. The basic structure for conversations in Andor’s Trail is that a conversation is made up of a list of these phrases, where each phrase has a list of possible replies. Each reply defines what the next phrase will be, and each phrase defines what available replies there are.
First, we assign an internal id to each phrase. It can be just about anything, as long as the id is unique over the whole game. Prefer to use the NPC’s name to make it unique, and prefer short ids in lowercase.
Let’s take one phrase from the above flowchart as an example of how just one phrase is represented:
This phrase defines three possible replies, and can be represented in the following format:
——————————————————– formatting problem
Phrase id | Text | Possible replies | ||
---|---|---|---|---|
gwend_2 | How may I help you? | Reply text | Next phrase id | |
That looks good, what is that you are having? | gwend_4 | |||
What do you do here? | gwend_3 | |||
Who are those noisy fellas over there? | gwend_5 |
Another phrase might look like this:
Which, in turn will be represented as the following information:
Phrase id | Text | Possible replies | ||
---|---|---|---|---|
gwend_5 | I don't know. They do make a lot of noise though. | Reply text | Next phrase id | |
Have you heard anything interesting from their shouting? | gwend_6 | |||
Let's go back to the other questions I had. | gwend_2 |
By separating the phrases from the replies, the whole conversation can then be defined like this - as just the list of phrases and what replies they have. In fact, all conversations in Andor’s Trail is stored as a huge list of phrases, with info on their corresponding replies, that in turn lead to other phrases.
As explained in the previous chapter, replies will lead to new phrases. In some cases, we want the something else to happen when selecting a reply, such as ending the conversation or initiating combat. For these special actions, there are some predefined phrase id:s that the replies can point to:
Phrase id | Meaning |
---|---|
X | Conversation ends. |
S | Conversation ends, and the player will start trading with the NPC that the conversation is with. The NPC will have items to sell available according to the droplist of the NPC. |
F | The NPC that the conversation is with will be turned hostile. Combat starts with the player having the first turn. |
R | Conversation ends, and the NPC that the conversation is with will be removed from the current map. |
These special phrase ids are not actually visible in the content editor. Instead, they are added if you select anything other than “NPC phrase in the drop-down list labelled “phrase leads to”.
Also, sometimes we just want to do a chain of phrases, where an NPC can speak several phrases while the player just clicks the “Next”-button to advance conversation. This is done by creating just one reply for a phrase, and using only an upper-case N as reply text (visible in the editor by the checkbox “Phrase leads directly to another phrase without replies”).
Reply text | Meaning |
---|---|
N | The player will only need to click “Next” to continue on to the next phrase. |
To create an actual quest using these conversations, we would need more things to happen other than just having the NPCs speak. For this, we introduce the concept of phrases being able to give rewards when reached. Rewards do not necessarily have to be positive of course :)
Each phrase has a list of rewards that will all be awarded as soon as the player reaches the phrase.
The possible types of rewards that a phrase can give are currently:
Type | Meaning |
---|---|
Quest progress | The player advances to a specified stage for some quest. |
Droplist | Player will be given all items specified by a droplist. |
Skill | Player will be given a level increase to a skill. Can of course also include skills that are otherwise hidden (quest skills). |
Actor condition | Either the player can be given one magnitude of a condition (poison/bless/rotworms), or the player can have a condition completely removed. |
Faction change | The player’s faction score for a certain faction can be changed. If a faction score reaches below zero, all monsters of that faction will be automatically turned hostile. |
The most common type is of course to advance some quest for the player. Each reward will define an id and a value of the reward. The values in id and value mean different things, depending on the type of reward:
Type | Meaning of “id” and “value” |
---|---|
Quest progress | id = The quest id that will be advanced. value = The quest stage that the player now has reached. |
Droplist | id = The id of the droplist that contains items that the player will be given. value = unused. |
Skill | id = internal id of the skill that will be awarded. value = unused. |
Actor condition | id = The internal id of the actor condition that will be added/removed. value = The duration of the condition. If specified as 999, it will be a permanent condition. If specified as -99, the condition will be removed. Unless value is 999 or -99, the condition will be added as magnitude 1. |
Faction change | id = Internal id of the faction whose score should change. value = How much the faction score should change. |
To create a complete quest, we also need some way of restricting the choices that the player can make, until some conditions have been reached. For example, the player should of course not be able to select the reply “Here is your map” while talking to Cileth until the player actually has the map itself.
For this, we use a concept of conditions that each reply might have. In order for a reply to be visible to the player, all of the conditions must be satisfied. For example, the reply “Here is your map” while talking to Cileth, might have a condition saying that the player both has to have the map in inventory, and also must have reached stage 30 of the quest (to ensure that the quest has been started).
Replies can require these types of conditions:
Condition type | Meaning |
---|---|
Inventory (removed) | The player must have some item in inventory, and the item(s) will be removed from the player’s inventory by selecting the reply. |
Inventory (kept) | The player must have some item in inventory. The item(s) will not be removed from the player’s inventory by selecting the reply. |
Worn | The player must currently be wearing some item in any of the equipment slots. The item will not be removed by selecting the reply. |
Quest progress | The player must have reached a specific stage in some quest in order to select the reply. Quest stages are typically specified as questname:stage. For example “cileth_map:30” means stage 30 in the quest with internal id “cileth_map”. |
It is important to note that a reply will be completely hidden for the player if at least one of the conditions are not satisfied.
The concept of phrases & replies is also used in Andor’s Trail to build complex conditional branching logic. Let’s look at the goblin boss monster Olgnuur’s dialogue as an example:
This is the basic conversation flow for Olgnuur. To make him use this conversation, we would put “olgnuur_1” as starting phrase in the definition of him as a monster, in the monster editor. However, consider these special cases that may occur:
In all of these cases, if we were to start conversation at “olgnuur_1” every time, the conversation would feel really odd - Olgnuur would seem to have a really bad memory. To fix this, we need to have some way of making the conversation start at different phrases depending on what the player has done earlier.
This is done in Andor’s Trail by using a phrase that does not have any display text. For phrases that do not have display text, the game will automatically advance conversation to the first reply that has all of its reply conditions satisfied. This way, we can re-use the concept of reply conditions discussed in the previous chapters, into creating a complex quest.
We introduce one of these phrases that does not have any display text at the start of Olgnuur’s dialogue:
Notice how reply 1 goes to phrase “olgnuur_2”, which in turn will engage combat. Reply 1 will be selected if the player previously has reached quest stage 70. Reply 2 will be selected if the player has reached stage 65, by previously receiving the map from Olgnuur, and will cause Olgnuur to just say that he wants to be left alone again. Reply 3 will be selected if the player has started the quest, but has not talked to Olgnuur before, and will trigger the conversation tree started by the phrase “olgnuur_1”. The fourth reply does not have any conditions, and will be selected if neither of the other replies were selected - for example, if the player has not started the quest at all.
Note that the game selects the replies in order, and proceeds with the first one where all conditions are satisfied.
This way, by placing phrase “olgnuur” as starting phrase, we can handle all the special cases described above. The game will evaluate the phrase “olgnuur” and pick one of its replies automatically, which will make Olgnuur say different things when starting his conversation. It will seem like he has remembered previous conversations.
Gwend’s dialogue from chapter 4.1 above is implemented in the dialogue editor: http://andors-trail.googlecode.com/git/AndorsTrailEdit/editor.html
The export of this conversation is as follows:
[id|message|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|]; {gwend|||{ {|gwend_r|cileth_map:10||||} {|gwend_1|||||} }|}; {gwend_r|Hello again.||{{N|gwend_2|||||}}|}; {gwend_1|Hello there, I am Gwend.||{{N|gwend_2|||||}}|}; {gwend_2|How may I help you?||{ {That looks good, what is that you are having?|gwend_4|||||} {What do you do here?|gwend_3|||||} {Who are those noisy fellas over there?|gwend_5|||||} }|}; {gwend_3|Oh, not much. Just enjoying my meal.||{{That looks good.|gwend_4|||||}}|}; {gwend_4|Yes, it sure is good. Boar stew.||{{N|gwend_2|||||}}|}; {gwend_5|I don\'t know. They do make a lot of noise though.||{ {Let\'s go back to the other questions I had.|gwend_2|||||} {Have you heard anything interesting from their shouting?|gwend_6|||||} }|}; {gwend_6|Oh yes, there was one thing I heard.||{{N|gwend_7|||||}}|}; {gwend_7|One of them spoke of someone called Cileth, or something like that.||{{N|gwend_8|||||}}|}; {gwend_8|Apparently, she lost something valuable to her.||{{N|gwend_9|||||}}|}; {gwend_9|I did not hear what it was though, but they sure seemed eager to recover it.||{{N|gwend_10|||||}}|}; {gwend_10|I\'m sure they said her name was Cileth. She lives somewhere here in Fallhaven apparently.|{{0|cileth_map|10|}}|{{N|gwend_11|||||}}|}; {gwend_11|That\'s all I know. Now, if you\'ll excuse me, I would really like to finish my meal here.||{{Thank you|X|||||}}|};
Notice how the export data contains each phrase with its replies on separate lines. The first phrase, with id “gwend”, is a phrase without text, as explained in section 4.5. Since it does not have any text, it will automatically select the first reply that matches. In this case, it means that if the player has reached stage 10 in quest “cileth_map”, Gwend will start talking at phrase “gwend_r”. Otherwise, gwend will start talking at “gwend_1”.
Notice also how phrase “gwend_10” rewards the player with a quest progress. If the player reaches this phrase, then stage 10 of quest “cileth_map” will be shown in the player’s quest log.
Olgnuur’s conversation from section 4.5. is also implemented in the content editor:
The export of this conversation is as follows:
[id|message|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|]; {olgnuur|||{ {|olgnuur_2|cileth_map:70||||} {|olgnuur_friend_1|cileth_map:65||||} {|olgnuur_1|cileth_map:40||||} {|olgnuur_notstarted|||||} }|}; {olgnuur_friend_1|You promised you leave us alone!||{{Sorry, just wanted to say hi again.|X|||||}}|}; {olgnuur_notstarted|Go away, pesky human!|||}; {olgnuur_1|Olgnuur angry!||{ {Why are you angry, Olgnuur?|olgnuur_4|||||} {Die, goblin scum!|olgnuur_2|||||} }|}; {olgnuur_2|Aargh, you one of them! You not rule us!||{{N|olgnuur_3|||||}}|}; {olgnuur_3|Goblins kill you!|{{0|cileth_map|70|}}|{{N|F|||||}}|}; {olgnuur_4|Pesky humans. Always coming here, stealing our things.||{{N|olgnuur_5|||||}}|}; {olgnuur_5|Killing our cattle.||{ {I am not here to steal anything. I am looking for a map.|olgnuur_6|||||} {Die, goblin scum!|olgnuur_2|||||} }|}; {olgnuur_6|Map? Olgnuur has map.||{ {What do you want in return for that map?|olgnuur_7|||||} {Good. I\'ll get that map from your cold corpse.|olgnuur_2|||||} }|}; {olgnuur_7|Pesky humans. Never leaving us alone.||{{What if I were to leave you alone, would you give me the map then?|olgnuur_8|||||}}|}; {olgnuur_8|Oh yes. Leave us alone. Yes. Map give.|{{0|cileth_map|50|}}|{ {Ok. I\'ll leave you alone, and you give me that map.|olgnuur_9|||||} {How about I just kill you instead?|olgnuur_2|||||} }|}; {olgnuur_9|Good. Here is map.|{{0|cileth_map|60|}{0|cileth_map|65|}{1|olgnuur_map||}}|{{Thank you.|X|||||}}|};
Some things to note in this conversation is the first phrase “olgnuur”, that also is a phrase without text, as described in section 4.5 above. It will ensure that Olgnuur’s dialogue starts with the correct phrase. Also note how phrase “olgnuur_9” gives two quest rewards, and a reward of a droplist with id “olgnuur_map” (which will have to be created).
Cileth’s conversation is left as an exercise for the reader. Consider what should happen when engaging conversation with her during the different stages of the quest. How could you make sure that Cileth only gives her reward once?
Once you have the quest ready, including the conversations, monsters and items required for it, you should be ready to publish it so that it can be included in the game. What should be posted is the exports from the content editor of the things that make up your quest; conversations, quest log, items, droplists and monsters.
The most common way of getting input is posting it on the game forums, and encouraging people to give feedback on it. You are also welcome to email it to someone in the development team, or post your quest on the issue tracker: http://code.google.com/p/andors-trail/issues/list
We are really looking forward to reading your content! Good luck with your quest!