Skip to main content

My First Quest

In this tutorial you will learn how to create a complete quest — from talking to an NPC, through the quest log, to receiving a reward.

How Do Quests Work in Gothic?

The quest system in Gothic is based on three elements:

  1. Dialogs (C_INFO) — conversations with NPCs that start and end quests
  2. Quest Log — entries visible to the player
  3. State variables — tracking quest progress

The C_INFO Class — Dialogs

Each dialog option is an instance of the C_INFO class:

FieldTypeDescription
npcintThe NPC we're talking to
nrintDisplay order (lower = higher)
conditionfuncCondition function — when the option is visible
informationfuncFunction executed when the option is selected
permanentintTRUE = option doesn't disappear after use
importantintTRUE = NPC speaks first (no player choice)
descriptionstringDialog option text

Step 1: Mission State Variable

First, define a variable to track quest progress. Add it to the mission constants file (e.g., Log_Constants.d):

// Mission states:
// 0 = not started
// LOG_RUNNING = in progress
// LOG_SUCCESS = completed successfully
// LOG_FAILED = failed

var int MIS_Konrad_FindAxe;

// Quest log topic name
const string TOPIC_Konrad_FindAxe = "Konrad's Axe";

Step 2: Mission Item

Create an item that the player needs to find (in Items/MissionItems.d):

instance ItMi_Topor_Konrada (C_Item)
{
name = "Konrad's Old Axe";
mainflag = ITEM_KAT_NONE;
flags = ITEM_MISSION; // mission item
value = 0; // not for sale
visual = "ItMw_010_1h_misc_axe_01.3DS";
material = MAT_WOOD;

description = name;
TEXT[5] = "Mission Item";
};
info

The ITEM_MISSION flag prevents the item from being sold or dropped.

Step 3: Dialog — Exit Conversation

Every NPC must have an exit conversation option. This is a standard element:

// --- End conversation ---
instance DIA_Konrad_EXIT (C_INFO)
{
npc = BAU_900_Konrad;
nr = 999; // at the very bottom
condition = DIA_Konrad_EXIT_Condition;
information = DIA_Konrad_EXIT_Info;
permanent = TRUE;
description = DIALOG_ENDE; // "End"
};

func int DIA_Konrad_EXIT_Condition ()
{
return TRUE; // always visible
};

func void DIA_Konrad_EXIT_Info ()
{
AI_StopProcessInfos (self); // close dialog window
};

Step 4: Dialog — Greeting (NPC Speaks First)

When the player approaches Konrad for the first time:

instance DIA_Konrad_Hallo (C_INFO)
{
npc = BAU_900_Konrad;
nr = 1;
condition = DIA_Konrad_Hallo_Condition;
information = DIA_Konrad_Hallo_Info;
permanent = FALSE; // only once
important = TRUE; // NPC speaks first
};

func int DIA_Konrad_Hallo_Condition ()
{
// Show only if quest hasn't been started yet
if (MIS_Konrad_FindAxe == 0)
{
return TRUE;
};
};

func void DIA_Konrad_Hallo_Info ()
{
// self = NPC (Konrad), other = player
AI_Output (self, other, "DIA_Konrad_Hallo_01_01"); //Hey, you there! Got a moment?
AI_Output (other, self, "DIA_Konrad_Hallo_15_01"); //What do you want?
AI_Output (self, other, "DIA_Konrad_Hallo_01_02"); //I lost my axe somewhere in the forest. Will you help me find it?
};
tip

Audio naming convention: DIA_Konrad_Hallo_01_0101 = NPC voice number, 01 = line number. 15 in the player's line refers to the hero's voice. The // comment after AI_Output must be on the same line — the Daedalus parser treats it as the dialog subtitle text.

Step 5: Dialog — Accepting the Quest

instance DIA_Konrad_Topor (C_INFO)
{
npc = BAU_900_Konrad;
nr = 5;
condition = DIA_Konrad_Topor_Condition;
information = DIA_Konrad_Topor_Info;
permanent = FALSE;
description = "I'll help you find the axe.";
};

func int DIA_Konrad_Topor_Condition ()
{
if (MIS_Konrad_FindAxe == 0)
{
return TRUE;
};
};

func void DIA_Konrad_Topor_Info ()
{
AI_Output (other, self, "DIA_Konrad_Topor_15_01"); //Alright, I'll look for your axe.
AI_Output (self, other, "DIA_Konrad_Topor_01_01"); //Thanks! Last time I saw it near the old cave to the north.

// === START QUEST ===
MIS_Konrad_FindAxe = LOG_RUNNING;

// Create topic in the quest log
Log_CreateTopic (TOPIC_Konrad_FindAxe, LOG_MISSION);
Log_SetTopicStatus (TOPIC_Konrad_FindAxe, LOG_RUNNING);
B_LogEntry (TOPIC_Konrad_FindAxe,
"Konrad lost his axe in the forest near the old cave to the north. I should look for it."
);

AI_StopProcessInfos (self);
};

Key Quest Log Functions:

FunctionDescription
Log_CreateTopic(topic, LOG_MISSION)Creates an entry in the quest log
Log_SetTopicStatus(topic, status)Sets status: LOG_RUNNING / LOG_SUCCESS / LOG_FAILED
B_LogEntry(topic, text)Adds a note to an existing entry

Step 6: Dialog — Returning the Item and Reward

instance DIA_Konrad_Topor_Oddaj (C_INFO)
{
npc = BAU_900_Konrad;
nr = 10;
condition = DIA_Konrad_Topor_Oddaj_Condition;
information = DIA_Konrad_Topor_Oddaj_Info;
permanent = FALSE;
description = "I have your axe.";
};

func int DIA_Konrad_Topor_Oddaj_Condition ()
{
// Show only when quest is active AND player has the axe
if (MIS_Konrad_FindAxe == LOG_RUNNING)
&& (Npc_HasItems (other, ItMi_Topor_Konrada) >= 1)
{
return TRUE;
};
};

func void DIA_Konrad_Topor_Oddaj_Info ()
{
AI_Output (other, self, "DIA_Konrad_Topor_Oddaj_15_01"); //I have your axe. Found it near the cave.

// Player gives the axe
B_GiveInvItems (other, self, ItMi_Topor_Konrada, 1);

AI_Output (self, other, "DIA_Konrad_Topor_Oddaj_01_01"); //Great! Take this gold as thanks.

// === REWARD ===
CreateInvItems (self, ItMi_Gold, 150);
B_GiveInvItems (self, other, ItMi_Gold, 150); // 150 gold
B_GivePlayerXP (100); // 100 XP

// === COMPLETE QUEST ===
MIS_Konrad_FindAxe = LOG_SUCCESS;
B_LogEntry (TOPIC_Konrad_FindAxe,
"I found Konrad's axe and returned it to him. In return, I received 150 gold coins."
);

AI_StopProcessInfos (self);
};

Step 7: Placing the Item in the World

In the Startup.d file (world startup function) place the axe at a location:

func void Startup_NewWorld ()
{
// ... other elements ...

// Place Konrad's axe at the cave waypoint
Wld_InsertItem (ItMi_Topor_Konrada, "NW_CAVE_NORTH_01");
};

Complete File Structure

A complete quest requires these files:

Scripts/Content/
├── _intern/Constants.d ← MIS_Konrad_FindAxe variable
├── Story/Log_Entries/
│ └── LOG_Constants.d ← TOPIC_Konrad_FindAxe constant
├── Items/
│ └── MissionItems.d ← ItMi_Topor_Konrada
├── Story/NPC/
│ └── BAU_900_Konrad.d ← NPC definition
├── Story/Dialoge/
│ └── DIA_BAU_900_Konrad.d ← all dialogs
└── Story/Startup.d ← Wld_InsertNpc + Wld_InsertItem

Summary

A complete quest in Gothic requires:

  1. A state variable tracking progress (0 → LOG_RUNNINGLOG_SUCCESS)
  2. A mission item with the ITEM_MISSION flag
  3. Dialogs with conditions based on quest state and owned items
  4. Quest log entries informing the player about progress
  5. Rewards (gold, XP, items)
  6. Registration of all files in Gothic.src in the correct order