Side Quests

Fleshcult has a fairly conventional quest system:

  • There are multiple QuestLines that operate independently.
  • Each QuestLine has a series of stages. The player sees their objectives for the current stage in the quest log on the Diary screen.
  • In Fleshcult a quest stage is just a text string, you can pick whatever you want.
    • QuestLines start in a state of None (no quotes). This indicates the player hasn’t been told about the quest yet.
    • The first transition is when the player becomes eligible to start the quest.

All the interesting bits live in the transitions between stages:

  • The quest log shows the name and desc fields for the next uncompleted transition in the quest
    • If you give a transition a name of None, it’s silent and doesn’t show in the log.
    • This is useful for that first transition I just mentioned, which is waiting to see if it can announce the quest.
  • Transitions have a list of Conditions. If the player meets all the conditions they’ve beaten that stage.
    • Except if you set condition_mode='any' on the transition, in which case just one will do it.
  • Each Condition can also show some text in the quest log.
  • You can add more than one transition from one stage to give the player branching options. Both are shown in the quest log. At the time of writing I haven’t tested this.
  • To notify the player they’ve beaten the stage and give them rewards, you’ve got the completion_event_ids list, which takes Constant IDs for EventCards. They can show messages and do stuff to the player.

If you poke around the codebase you’ll also see Missions, but they’re entirely different. When a recruit is listed on the Visit tab, that’s a Mission.

Checking a quest’s stage

Or you may prefer to unlock stuff from elsewhere by checking quest state:

player.quests.is_quest_stage_complete('questline.my_awesome_quest', 'pope_betrayed_stage')

Returns True or False

Defining a Side Quest

Note, things look slightly different when the transitions are Schemes

import faust.MathUtil
import faust.RandUtil
import faust.QuestDefinition
import faust.Building

from faust.EventCard import EventCard
from faust.Constant import get_constant, del_constant
from faust.QuestDefinition import QuestLine, StageCondition, RangeCondition

def init():
    quest = QuestLine('questline.my_awesome_quest', [])

    # Wait to announce quest
    quest.add_transition(
        None,          # Stage from
        'announced',   # Stage to
        None,          # name=None, silently for conditions to be met
        '',            # desc is empty too
        [RangeCondition('player.num_tomes', min_incl=1)],   # Run when player has 1 tome
        completion_event_ids=['eventcard.my_quest_intro'])  # announcement

    # Make eventcard.my_quest_intro
    EventCard('my_quest_intro', "A Quest!",
        """Check your quest log""")

    # First challenge to player
    quest.add_transition(
        'announced',   # Stage from
        'won',         # Stage to
        'Collect a tome',
        "Bet you can't collect a 2nd tome",
        [RangeCondition('player.num_tomes', min_incl=2)],
        completion_event_ids=['eventcard.my_quest_won'])

    EventCard('my_quest_won', "You Win",
        """Woo hoo!""")

    faust.QuestDefinition.all_questlines.append(quest)

def deinit():
    del_constant("questline.my_awesome_quest")
    del_constant("eventcard.my_quest_intro")
    del_constant("eventcard.my_quest_won")

    # Filter out deregistered quests
    faust.QuestDefinition.all_questlines = list([quest for quest in faust.QuestDefinition.all_questlines
        if not quest.is_constant_missing()])