create_a_new_quest_line_for_the_npc_regarding_fishes_and_krapfens

Create a new quest line for the NPC regarding Fishes and Krapfens pt.1

Now we have to create a brand new questline to attach to the Npc we have already created in the previous guides.
Let's begin by creating a quests folder in our mod folder structure:

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\Quests

After that we will create also a Sprites folder inside our Quests folder.
First thing we will place a 128x128px png file in the sprites folder for our quest to have a picture shown in the various panels: save this in:

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\Quests\Sprites\mod_quest_1.png

Then let's proceed to the creation of a brand new quest file in the quests folder:

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\Quests\mod_quest_1.json

Edit it and place this content inside it:

{
  "questType": "BaseQuest",
  "questId": "mod_quest_1",
  "questSpriteName": "mod_quest_1.png",
  "isReoccurring": false,
  "startingQuestDialogueId": "mod_quest_1_start_dialogue",
  "okQuestDialogueId": "mod_quest_1_ok_dialogue",
  "koQuestDialogueId": "mod_quest_1_ko_dialogue",
  "achievementsOnStart": "TalkToANpc",
  "achievementsOnComplete": "CompleteAllMiniquest,MiniquestComplete",
"rewards": [
	{
	  "questItemId": "krapfen_hoven_boxed",
	  "questItemType": "BoxedFurnituresItem",
	  "questItemQuality": 3,
	  "questItemAmount": 1
	}
  ],
  "prerequisites": [
	{
	  "questItemId": "Light the Bob Stout",
	  "questItemType": "FoodItem",
	  "questItemAmount": 1,
	  "isToDestroyOnUse": true
	}
  ],
  "dialogues": [
	{
	  "questDialogueId": "mod_quest_1_start_dialogue",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "",
	  "buttonAFunction": "",
	  "buttonAParameter": "",
	  "buttonBText": "mod_quest_1_start_dialogue_btnB",
	  "buttonBFunction": "OpenDialogue",
	  "buttonBParameter": "mod_quest_1_dialogue2",
	  "buttonCText": "mod_quest_1_start_dialogue_btnC",
	  "buttonCFunction": "Abort",
	  "buttonCParameter": ""
	},
	{
	  "questDialogueId": "mod_quest_1_dialogue2",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "mod_quest_1_dialogue2_btnA",
	  "buttonAFunction": "OpenDialogue",
	  "buttonAParameter": "mod_quest_1_help_dialogue",
	  "buttonBText": "mod_quest_1_dialogue2_btnB",
	  "buttonBFunction": "Dismiss",
	  "buttonBParameter": "",
	  "buttonCText": "mod_quest_1_dialogue2_btnC",
	  "buttonCFunction": "EndQuest",
	  "buttonCParameter": ""
	},
	{
	  "questDialogueId": "mod_quest_1_ok_dialogue",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "",
	  "buttonAFunction": "",
	  "buttonAParameter": "",
	  "buttonBText": "",
	  "buttonBFunction": "",
	  "buttonBParameter": "",
	  "buttonCText": "mod_quest_1_ok_dialogue_btnC",
	  "buttonCFunction": "Dismiss",
	  "buttonCParameter": ""
	},
	{
	  "questDialogueId": "mod_quest_1_ko_dialogue",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "",
	  "buttonAFunction": "",
	  "buttonAParameter": "",
	  "buttonBText": "mod_quest_1_ko_dialogue_btnB",
	  "buttonBFunction": "OpenDialogue",
	  "buttonBParameter": "mod_quest_1_help_dialogue",
	  "buttonCText": "mod_quest_1_ko_dialogue_btnC",
	  "buttonCFunction": "Abort",
	  "buttonCParameter": ""
	},
	{
	  "questDialogueId": "mod_quest_1_help_dialogue",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "",
	  "buttonAFunction": "",
	  "buttonAParameter": "",
	  "buttonBText": "",
	  "buttonBFunction": "",
	  "buttonBParameter": "",
	  "buttonCText": "mod_quest_1_help_dialogue_btnC",
	  "buttonCFunction": "Dismiss",
	  "buttonCParameter": ""
	}
  ]
}

This long file is the representation of a single quest in the game.
We will now examine every entry of the file and explain its function. So let's start from the head section.

It's comprised of the following lines:

  "questType": "BaseQuest",
  "questId": "mod_quest_1",
  "questSpriteName": "mod_quest_1.png",
  "isReoccurring": false,
  "startingQuestDialogueId": "mod_quest_1_start_dialogue",
  "okQuestDialogueId": "mod_quest_1_ok_dialogue",
  "koQuestDialogueId": "mod_quest_1_ko_dialogue",
  "achievementsOnStart": "TalkToANpc",
  "achievementsOnComplete": "CompleteAllMiniquest,MiniquestComplete",
questType

Represents the type of the quest to be achieved. It's referencing a type of Object that must be implemented in the source code. So the possibilities are limited to a finite number of options, alreaby implemented. Others may be implemented in the future if needed.
The list is:

  • BaseQuest: It's a simple Desiderata type quest. The Npc will need one or more objects and will give back one or more items back. Prerequisites and rewards are used to specify the needed objects and the rewards. Prerequisite items must be present in the base player inventory to be eligible for quest completion (not in bags)!
  • DoorQuest: In this type of quest a door will be permanently opened if the player fullfills the quest's items prerequisites. Prerequisite items must be present in the base player inventory to be eligible for quest completion (not in bags)!
  • EmptyQuest: Empty quests are just quest with no success prerequisite. They will succeed everytime. Their usage is for one shot dialogues that you don't want to repeat, for example. Be creative ;-).
  • ShopQuest: Npcs that are running a shop will be attached with a reoccurring ShopQuest. It will open the referenced shop anytime the player will interact with the Npc.

Other QuestTypes will be developed in the future!

questId

This property will contain a uniqueid to assign to the quest.

questSpriteName

This will contain the sprite name of the 128x128px png sprite file to show in the quest panel. It will need to reside in the Sprites folder. (We saved before the wookie image, you remember?)

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\Quests\Sprites

isReoccurring

If this is set to true the quest will be added to the completed quests list of the player and will not be shown again to him. The quest line will continue with the next quest. Otherwise if set to false the quest will be presented over and over forever. It's used in ShopQuest quests, for example.

startingQuestDialogueId, okQuestDialogueId, koQuestDialogueId

Every quest in Hard Times must have at least 3 dialoques configured: start, ok and ko. Those are the minimum requirements of a quest (except for the EmptyQuest which never uses the ko dialogue). So we have to set the reference to the 3 dialogues that will be detailed later on in the code.

achievementsOnStart

Should we fire some achievement (you can specify multiple achievements separated by a comma “,”) on starting the quest?

achievementsOnComplete

Should we fire some achievement (you can specify multiple achievements separated by a comma “,”) on completing the quest?

Lets take a look at the prerequisites and rewards section where we specify what's needed to complete the quest and whats rewarded for it.

"rewards": [
	{
	  "questItemId": "krapfen_hoven_boxed",
	  "questItemType": "BoxedFurnituresItem",
	  "questItemQuality": 3,
	  "questItemAmount": 1
	}
  ],
  "prerequisites": [
	{
	  "questItemId": "Light the Bob Stout",
	  "questItemType": "FoodItem",
	  "questItemAmount": 1,
	  "isToDestroyOnUse": true
	}
  ]

As we can see they are collections of questItems, specifing each a item id, a item type and the items amount (needed in case of a prerequisite, given in case of a reward). In case of a reward we will specify also a questItemQuality for the items to be spawned. In the case of a prerequisite we will specify if the item is to destroy on use or if it will remain in the player's possession.
Please note that if we specify a reward item with a questItemType = “Money”, we will give the questItemAmount of money units to the player.

Dialogues are the most complex part of the file. They specify the dialogues text and interaction buttons present on every single panel. A quest always starts with a starting dialogue, as specified in the head section.
When a dialogue is presented a text is fetched from the localization dictionary. Also a sprite is shown as specified in the head section.
A quest can have from one to three interaction buttons. They are usually dialogues responses. Each button has his own label and must be attached with a function and a optional parameter.
The available functions are:

  • Abort: The quest is abandoned and not flagged as active anymore.
  • Dismiss: The quest dialogue is closed. The quest remains active anyway.
  • EndQuest: this asks the game to veryfy the quest condition fulfillments. In positive case it opens the “okQuestDialogueId” dialogue. Otherwise the “koQuestDialogueId” will be opened.
  • NextQuest: Closes as completed the current quest and directly fires the next quest in the questline, opening its starting dialogue.
  • OpenDialogue: Opens another dialogue in the quest. The quest to be opened is specified in the button optional parameter.

So let's look at the first dialogue in the quest:

	{
	  "questDialogueId": "mod_quest_1_start_dialogue",
	  "questDialogueTitle": "My Awesome Quest pt.1",
	  "buttonAText": "",
	  "buttonAFunction": "",
	  "buttonAParameter": "",
	  "buttonBText": "mod_quest_1_start_dialogue_btnB",
	  "buttonBFunction": "OpenDialogue",
	  "buttonBParameter": "mod_quest_1_dialogue2",
	  "buttonCText": "mod_quest_1_start_dialogue_btnC",
	  "buttonCFunction": "Abort",
	  "buttonCParameter": ""
	},

We can see we have to specify an unique questDialogueId and a “questDialogueTitle” for the panel. Then we specify the buttons data.
As you can see this time we will not use the buttonA (the uppermost button) as we will leave all of the three fields empty.
In buttonB we can see the same fields populated:

  • buttonBText: is the id of the label in the localization dictionary to contain the button's text. We will specify them later.
  • buttonBFunction: the name of one of the functions specified before.
  • buttonBParameter: here we will place the optional parameter required by some functions.

The parameters are specified for each of the three buttons: A, B, C.
We can note the buttonBParameter contains the questDialogueId of the dialogue to be opened by that button. This way you can navigate through dialogues.
As you can see there are five dialogues specified in this quest. They are the three mandatory ones and two extra ones. In theory our quest could function as is. We have to do two more things yet: assign the quest to our npc and write down the quest actual dialogues and responses texts, since without them it will make no sense to the player as a bunch of meaningless labels.
Let's try anyway to attach it to our npc and test it out to see if we made errors during our way.

Let's go back and open our new npc, that we made in the previous guides:

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\QuestGiversNpc\modder_npc.json

Edit the file so it will look like this:

{
  "questGiverNpcId": "modder_npc",
  "scene": "zero",
  "posX": 0,
  "posY": -8,
  "questList": [
     "mod_quest_1"
  ],
  "bodyIndex": 2,
  "hairIndex": 0,
  "beardIndex": -1,
  "dressId": "polo",
  "dressType": "ClothingItem",
  "hasBreast": false,
  "hatId": "",
  "hatType": "",
  "proxyId": "",
  "proxyType": "",
  "wanderRange": 2
}

We just modified here:

"questList": [
	"mod_quest_1"
],

Adding our new quest to the questList of our npc.

Lastly we have to modify our mod's descriptor file to add the “questsFolder” property, and set it the the “Quests” value like the name of our quests folder. So open the mod's descriptor file in:

C:\Users\{YOUR USERNAME}\AppData\LocalLow\RadicalFiction\HARDTIMES\Mods\MyMod_MODPKG\Descriptor.json

And edit it to add our new property

{
  "modName": "MyMod_MODPKG",
  "author": "RadicalFiction",
  "gameVersion": "",
  "langFolder": "Lang",
  "itemsFolder": "Items",
  "shopsFolder": "Shops",
  "spawnersFolder": "Spawners",
  "figuresFolder": "Figure",
  "furnituresFolder": "Furnitures",
  "recipesFolder": "Recipes",
  "fishingSpotsFolder": "FishingSpots",
  "questGiversNpcsFolder": "QuestGiversNpc",
  "questsFolder": "Quests"
}

If everything went well you should now be able to start again the game with no errors(!). Be sure you have your new mod active and start a new game.
Now the guy we added to the game in the last guides will give us a brand new unintelligible quest for us to solve.
(amazing indeed)
In the second part of this guide we will specify the dialogues labels so that our new quest will be playable at it's best!

If you have problems or find errors in this guide please get in touch at info@tempi-duri.net.

You could leave a comment if you were logged in.
  • create_a_new_quest_line_for_the_npc_regarding_fishes_and_krapfens.txt
  • Last modified: 2019/02/12 10:59
  • by thorfinio