Modding:Quests
![]() |
This page is about modding. See the modding overview for an abstract on modding. |
This page will step you through writing your own questline. First, we will break down some of the common components of quests.
Quests.xml
The game defines quests in the Quests.xml
file. Each quest is primarily broken down into the following:
- A top-level
<quest>
tag that defines high-level properties of the quest, including the faction that assigned it (if any), journal accomplishments that should be added upon completing the quest, and so on, and <step>
nodes that define individual steps of the quest.
For example, here is the quest definition for O Glorious Shekhinah!:
<quest
Name="O Glorious Shekhinah!"
Level="3"
System="TravelToStiltSystem"
Accomplishment="On the recommendation of a proselyte, you visited the merchant bazaar and grand cathedral at the Six Day Stilt."
Hagiograph="=name= trekked through the salt pans, north and west, to the merchant bazaar and grand cathedral of the Six Day Stilt. There, the stiltfolk sang hymns in the sultan's honor."
HagiographCategory="VisitsLocation">
<step Name="Make a Pilgrimage to the Six Day Stilt" XP="1500">
<text>Journey through the Great Salt Desert to visit the merchant bazaar and Mechanimist cathedral, where a proselyte asked you to make on offering of a trinket.</text>
</step>
</quest>
IQuestSystem
A common component for many (but not all) quests is custom, per-quest systems that advance a player's progression through the quest as they achieve various objectives. Continuing our example from earlier, here's the system used by O Glorious Shekhinah!, TravelToStiltSystem
:
using System;
namespace XRL.World.Quests;
[Serializable]
public class TravelToStiltSystem : IQuestSystem
{
public override void Register(XRLGame Game, IEventRegistrar Registrar)
{
Registrar.Register(ZoneActivatedEvent.ID);
}
public override bool HandleEvent(ZoneActivatedEvent E)
{
if (E.Zone.ZoneID == "JoppaWorld.5.2.1.1.10" || E.Zone.ZoneID == "JoppaWorld.5.2.1.2.10")
{
The.Game.FinishQuestStep("O Glorious Shekhinah!", "Make a Pilgrimage to the Six Day Stilt", -1, CanFinishQuest: true, E.Zone.ZoneID);
}
return base.HandleEvent(E);
}
// GetInfluencer is primarily used to determine who should be referenced when
// naming an item. If the player successfully rolls an item naming opportunity
// upon completing the quest, they will be able to name their item after the
// culture of either Wardens Esther or Tszappur.
public override GameObject GetInfluencer()
{
if (50.in100())
{
return GameObject.FindByBlueprint("Wardens Esther");
}
return GameObject.FindByBlueprint("Tszappur");
}
}
The main thing that this quest system does is register an event handler to check for ZoneActivatedEvent
and determine whether the player has arrived at the Six Day Stilt. If they have, then the quest is completed.
IQuestSystem versus QuestManager
QuestManager
is the old interface that used to manage the progression of quests. While code usingQuestManager
is still present in the codebase, new code should in general preferIQuestSystem
instead.
Quest progression
Giving quests to players
There are various ways to give a quest to a player in XML or C#. On the XML-only side, the StartQuest
part generator for conversations can grant a player a quest. Here is an example of StartQuest
usage from Argyve's dialogue, starting the quest A Canticle for Barathrum.
<node ID="CanticleAccept3">
<text>
Here you are. Now, go! Off with you! May you live long enough to do my bidding. Away, away!
</text>
<choice GotoID="End" StartQuest="A Canticle for Barathrum">
<text>Farewell, Argyve.</text>
<part Name="ReceiveItem" Blueprints="Droid Scrambler,Argyve's Data Disk" Identify="All" />
</choice>
</node>
With scripting it is possible to start the quest using The.Game.StartQuest
, e.g.
The.Game.StartQuest("A Canticle for Barathrum");
Completing steps of a quest
In a conversation, you can use the CompleteQuestStep
part generator to mark the completion of a step of a quest.
To complete a quest step from C#, you can call The.Game.FinishQuestStep
. This can be called from anywhere during the game; for example, here's a snippet from the FinishQuestStepWhenSlain
part (used to -- as the name suggests -- complete a quest step after slaying a creature):
using System;
namespace XRL.World.Parts;
[Serializable]
public class FinishQuestStepWhenSlain : IPart
{
public string Quest;
public string Step;
public string GameState;
public virtual bool Clean => true;
// ...
public virtual void Trigger()
{
if (GameState != null)
{
The.Game.SetIntGameState(GameState, 1);
}
if (!The.Game.TryGetQuest(this.Quest, out var Quest))
{
if (!RequireQuest)
{
return;
}
Quest = The.Game.StartQuest(this.Quest);
}
The.Game.FinishQuestStep(Quest, Step);
if (Clean)
{
ParentObject.RemovePart(this);
}
}
}
If you wish to signal the failure of a game step, you can use The.Game.FailQuestStep(QuestName, QuestStep)
instead.
Completing a quest
A quest will automatically be marked as completed when you have completed all of its steps. However, in some cases you may want to manually trigger the completion of a quest, e.g. if the player (for whatever reason) completed the quest without finishing all of its objectives.
To manually complete a quest from a conversation, you can use FinishQuest
. Here's the conversation node from Otho's script that completes Decoding the Signal:
<node ID="PresentTheDisk">
<text>
Well done, =factionaddress:Barathrumites=. Present the disk.
</text>
<choice GotoID="InterpretSignal" CompleteQuestStep="Decoding the Signal~Return to Grit Gate|6000" FinishQuest="Decoding the Signal">
<text>[Give Otho the disk]</text>
<part Name="GritGateHandler" Rank="Journeyfriend" />
</choice>
</node>
From C#, you can call The.Game.FinishQuest(QuestName)
. There also exists a method for failing quests, as there does for failing steps; this method is The.Game.FailQuest(QuestName)
.
Example: Nima Ruda's fetch quest
![]() |
This article is a stub. You can help Caves of Qud Wiki by expanding it. |
|