Questing Implementation [SOLVED]

Anonynn
09 Aug 2016, 20:24

I tried looking up in the forums about implementing a "Questing System", but I couldn't find anything about it. I was wondering if someone has any suggestions about their own :)

I was thinking a global command with something like quest.object1, attribute, completed/not completed. But I'm not sure.


hegemonkhan
09 Aug 2016, 22:02

Jay and Pixie can probably create a really fancy/advanced quest/mission/task/award/trophy/etc system, but your idea is how I would do it too (with a bit more stuff for its implementation), with my limited code ability.

// when a quest is discovered/known/made-available, you need to do this:

add_quest_status_stringdictionary_function (NAME_OF_QUEST)

// --------------------------

// when a quest is completed, you need to do this:

update_quest_status_stringdictionary_function (NAME_OF_QUEST)

// --------------------------

<command name="quest_screen_command">
  <pattern>quest</pattern>
  <script>
    quest_screen_function
  </script>
</command>

<function name="quest_screen_function">
  ClearScreen
  msg ("Quest Screen:")
  numbering = 0
  foreach (quest_name_variable, game.pov.quest_stringlist_attribute) {
    numbering = numbering + 1
    msg ("")
    msg (numbering + ". " + quest_name_variable + " Quest: " + StringDictionaryItem (game.pov.quest_status_stringdictionary_attribute, quest_name_variable))
    msg ("")
    msg (StringDictionaryItem (global_data_object.quest_description_stringdictionary_attribute, quest_name_variable))
  }
  wait {
    ClearScreen
  }
</function>

<function name="add_quest_status_stringdictionary_function" parameters="quest_name_parameter">
   // HK edit: I forgot this needed code:
  if (not HasAttribute (game.pov, "quest_status_stringdictionary_attribute")) {
    game.pov.quest_status_stringdictionary_attribute = NewStringDictionary()
  }
  dictionary add (game.pov.quest_status_stringdictionary_attribute, quest_name_parameter, "incomplete")
</function>

<function name="update_quest_status_stringdictionary_function" parameters="quest_name_parameter">
  // I wasn't sure if the Value can be changed directly, and if it can do changed directly, can it be done with 'set', or is it done some other way and how? We need Pixie or Jay to answer this for us, lol. So, I just did this instead below:
  dictionary remove (game.pov.quest_status_stringdictionary_attribute, quest_name_parameter)
  dictionary add (game.pov.quest_status_stringdictionary_attribute, quest_name_parameter, "completed")
</function>

<object name="player">
  <attr name="quest_stringlist_attribute" type="simplestringlist">quest_name_1;quest_name_2;etc</attr> // as you discover/know quests, add them to this list: your current list of known/discovered quests
</object>

// if you want etc Player Objects:
<object name="player2">
  <attr name="quest_stringlist_attribute" type="simplestringlist">quest_name_1;quest_name_2;etc</attr> // as you discover/know quests, add them to this list: your current list of known/discovered quests
</object>

// etc Player Objects, if you want/need

<object name="global_data_object">
  <attr name="quest_stringlist_attribute" type="simplestringlist">quest_name_1;quest_name_2;etc</attr> // list of ALL quests
  <attr name="quest_description_stringdictionary_attribute" type="stringdictionary">
    <item>
      <key>quest_name_1</key>
      <value>DESCRIPTION_OF_QUEST</value>
    </item>
    <item>
      <key>quest_name_2</key>
      <value>DESCRIPTION_OF_QUEST</value>
    </item>
    <item>
      <key>etc</key>
      <value>DESCRIPTION_OF_QUEST</value>
    </item>
  </attr>
</object>

ask if you got any questions, need any explanation, and/or if anything is unclear or confusing.

P.S.

let me know if you want to add in other details, such as what the reward is for completing the quest, and whatever else such details you want included. And, I'll adjust or add to the code to be able to do this for you.


Anonynn
10 Aug 2016, 03:03

I'm not sure I need it that complicated @_@. I think I could do something like...

quest.object - attributes
recieved.boolean.false (true if the quest has been received/visible. False if invisible/not received)
completed.boolean.false (true if completed)

I'd rather not create a bunch of object though because they would just fill up the player's inventory.

Maybe something like...

player.objects, attributes
quest1.boolean.false
changedquest1.script

I dunno.

---------------------UPDATE-------------------------
Actually, I figured out a way easier way.

Make ...

Global Command: quests
Attributes
quest1.boolean.false (true if the quest has been received)
quest1flag.boolean.false (true if the quest has been completed)
changedquest1.script
if (quests.quest1flag=False) {
}
else {
  msg ("<br/>You've completed Quest 1! <br/><br/>You gain...<br/>")
}
Main Command Script
msg ("{if quests.quest1=True:Quest 1: <i>You're trying to complete your first quest!</i>{if quests.quest1flag=True: **<u>COMPLETED</u>**}}")

Then when you want the player to start a quest, you add to the room or wherever.

quests.quest1=True (this is a set variable script)

Hope this helps everyone wanting to do this!


The Pixie
10 Aug 2016, 07:46

It might be better to use an int rather than a boolean. That way you can track when the player is in the quest. At the very least you have four states:

Quest not given
Quest given but not completed
Quest completed
Reward given

You could have several hoops for the player to jump through in the middle of the that.


hegemonkhan
10 Aug 2016, 12:01

there's not too much going on with my code, but it's able to be expanded pretty easily, but of course the code itself is complicated, despite what it is doing isn't that much, lol.

The code is mainly complex to make it handle most of the work for you, and to be able to be easily expanded upon based on your wants/needs.

you put all of your quests (names) in your game into the 'global_data_object.quest_stringlist_attribute' list, for example:

<object name="global_data_object">
  <attr name="quest_stringlist_attribute" type="simplestringlist">rescue_kitten;rescue_princess;bring_girl_flowers;etc</attr>
</object>

and if you put in your descriptions/briefing/info/reward/etc of ALL of the quests (this code can be adjusted to handle what you want, additional info/rewards/details/etc and/or changed around if you don't like it):

<attr name="quest_description_stringdictionary_attribute" type="stringdictionary">
    <item>
      <key>rescue_kitten</key>
      <value>You best friend's baby kitten crawled up into a tree and is too scared to climb back down</value>
    </item>
    <item>
      <key>rescue_princess</key>
      <value>The princess has been taken by a dragon, go into the dragon's lair and slay the dragon, to rescue her.</value>
    </item>
    <item>
      <key>give_flowers_to_girl</key>
      <value>There's a girl that you like, go buy some flowers to then give them to her</value>
    </item>
  </attr>

as you discover quests, you add them to that Player Object's 'quest_stringlist_attribute', via using the 'add_quest_status_stringdictionary_function (QUEST_NAME)'

upon typing in 'quest', you'll see your current quest information (you won't see the quests you've not discovered yet - don't want to spoil the game's future/further progress/content quests --- this is the purpose of the 'quest_stringlist_attribute' for each of your Player Objects, this is the list of your currently discovered quests, so that you're not seeing all of the quests in the game to be discovered - not spoiling the game), for example:

Quest Screen:

1. Rescue Kitten Quest: incomplete

You best friend's baby kitten crawled up into a tree and is too scared to climb back down

2. Rescue Princess Quest: incomplete

etc etc etc

3. Give Flowers to Girl Quest: incomplete

etc etc etc

and upon completing a quest, use this Function: 'update_quest_status_stringdictionary_function (QUEST_NAME)'.

and now, your 'quest_screen_command' Command's display will be for example:

Quest Screen:

1. Rescue Kitten Quest: completed

You best friend's baby kitten crawled up into a tree and is too scared to climb back down

2. Rescue Princess Quest: completed

etc etc etc

3. Give Flowers to Girl Quest: incomplete

etc etc etc

4. Teach townspeople to grow food quest: incomplete

etc etc etc

if you just want something really simple:

just have a bunch of Boolean (or String or Integer) Attributes, which you adjust as needed, and then have a Command to show/display them of course

<object name="quest_object">
  <attr name="rescue_kitten_quest_is_completed_boolean_attribute" type="boolean">false</attr>
  <attr name="rescue_princess_quest_is_completed_boolean_attribute" type="boolean">false</attr>
  <attr name="give_flowers_to_girl_quest_is_completed_boolean_attribute" type="boolean">false</attr>
</object>

<command name="quest_command">
  <pattern>quest</pattern>
  <script>
    // this is a very inefficient way of doing it: manually/individually, if you want better ways, see my previous post for example, and ask for help if you're interested in doing it in a more efficient way:
    ClearScreen
    msg ("Quest Screen")
    msg ("")
    msg ("Rescue Kitten Quest: " + quest_object.rescue_kitten_quest_is_completed_boolean_attribute)
    msg ("Rescue Princess Quest: " + quest_object.rescue_princess_quest_is_completed_boolean_attribute)
    // etc etc msg quest scripts
    wait {
      ClearScreen
    }
  </script>
</command>