Quest Machine Saved Game Question

Announcements, support questions, and discussion for Quest Machine.
Post Reply
User avatar
Tony Li
Posts: 22107
Joined: Thu Jul 18, 2013 1:27 pm

Quest Machine Saved Game Question

Post by Tony Li »

Hi Tony, I'm having a problem with Quest Machine. I set a single quest giver (i.e QuestMaster) that holds all quests given to player, the QuestMaster can give quest to player just fine but why the quest state on QuestMaster side doesn't update when I finish the quest (listed as success on quest journal) thus the quest states on PlayerPrefs are always set to
"unassigned", as in the game is unable to save quest states.

I've put the quests on quest database correctly and set both "include in save data" and "save across scene change" for both QuestMaster and Journal, the quest is started from a Dialogue System conversation (i.e GiveQuest("QuestMaster", "cursedSanctuaryScroll")) but whether I put any quest on Dialogue Editor's Quests/Items list doesn't affect anything. What
step did I miss at setting up the QuestMaster?
If you're using Quest Machine quests, you don't have to add them to the Dialogue System's database in the Dialogue Editor. However, it's fine for you to add them as empty quests so you can easily reference the quest names in conversations' "..." dropdown menus.

When the player accepts a quest from the NPC (QuestMaster), the player's QuestJournal will receive a copy of the quest. When the player completes the quest, this copy's state will be set to Success. The original quest in QuestMaster's QuestGiver list will be unchanged, except for the cooldown time if it's a repeatable quest with a cooldown duration.

Since you've ticked Include In Save Data and Save Across Scene Changes for the player's QuestJournal and QuestMaster's QuestGiver, this information should be included in saved games. When you load the saved game, the copy in the player's QuestJournal should still be set to Success. The original in the QuestMaster's QuestGiver list should still have its original values.

If that's not the case in your project, please check the Console window for any errors or warnings. Also make sure the save system is fully set up with these components: SaveSystem, data serializer (e.g., JsonDataSerializer), and data storer (e.g., PlayerPrefsSavedGameDataStorer). You can tick the Debug checkboxes on the components to log extra info to the Console.

If that doesn't help, please feel free to send a reproduction project to tony (at) pixelcrushers.com. I'll be happy to take a look.

You can also tick the Debug checkboxes on the save system components in Quest Machine's included demo scene. If you play this scene, you can see what kind of information the Debug checkboxes log when you save and load a game.
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: Quest Machine Saved Game Question

Post by RX-310 »

Also make sure the save system is fully set up with these components: SaveSystem, data serializer (e.g., JsonDataSerializer), and data storer (e.g., PlayerPrefsSavedGameDataStorer).
Got all those set up on a manager object, I can save and load Dialogue System database with that fine, but not Quest Machine. I'm using PersistentDataManager.GetSaveData() to get the save data string then store it into a file.

Apparently my QuestJournal doesn't even save its quest list to saved game, every time I restart the game the list on quest journal is empty.
User avatar
Tony Li
Posts: 22107
Joined: Thu Jul 18, 2013 1:27 pm

Re: Quest Machine Saved Game Question

Post by Tony Li »

RX-310 wrote: Wed Jan 22, 2020 8:53 pmI'm using PersistentDataManager.GetSaveData() to get the save data string then store it into a file.
Ah! That's the key. PersistentDataManager only handles the Dialogue System's database info.

Since you have those save system components set up, get the save data string like this:

Code: Select all

using PixelCrushers;
...
string s = SaveSystem.Serialize(SaveSystem.RecordSavedGameData());
To make sure the Dialogue System's database info gets included in this string, add a DialogueSystemSaver to the Dialogue Manager. The DialogueSystemSaver script is basically a save system wrapper for PersistentDataManager.GetSaveData().

To reapply the string when loading a game, use this:

Code: Select all

SaveSystem.ApplySavedGameData(SaveSystem.Deserialize<SavedGameData>(s));
RX-310
Posts: 22
Joined: Tue Jan 21, 2020 7:50 pm

Re: Quest Machine Saved Game Question

Post by RX-310 »

Since you have those save system components set up, get the save data string like this:
Hmmm, I set the code on my save method, but the string only returns this as if the quest journal saver isn't saving

Code: Select all

{"m_sceneName":"MainGameScene","m_list":[]}
What am I missing? I already set "include in save data", "save across scene change" and save key for both journal and quest master. Do I need to define the Quest Machine Configuration object in the save method as well?

update: nevermind, it didn't work because I called RecordSavedGameData during scene transition where the quest journal object is disabled, now I set it to after dialogue is finished the save is now working.


And for another question, now that the quest journal can load normally, how I can make the dialogue directly plays the CurrentQuestState == "success" node, since when I restarted the scene the dialogue still plays the CurrentQuestState == "unassigned" node instead.
User avatar
Tony Li
Posts: 22107
Joined: Thu Jul 18, 2013 1:27 pm

Re: Quest Machine Saved Game Question

Post by Tony Li »

Hi,
RX-310 wrote: Wed Jan 22, 2020 10:27 pmAnd for another question, now that the quest journal can load normally, how I can make the dialogue directly plays the CurrentQuestState == "success" node, since when I restarted the scene the dialogue still plays the CurrentQuestState == "unassigned" node instead.
Does your conversation have different branches for the different quest states?

Please see the example conversations that come with Quest Machine's Dialogue System integration. For example, the "Harvest Carrots" conversation looks like this:

questMachine_DS_Conv.png
questMachine_DS_Conv.png (33.65 KiB) Viewed 929 times

The top-level branches check the quest state.

Also keep in mind that the save system typically waits one frame before applying save data. (You can configure the number of frames on the SaveSystem component.) This allows time for other GameObjects to initialize themselves before receiving save data. But this means that at the very start of the scene the save data, such as saved quest states, may not have been applied yet.

If you're starting a conversation OnStart, wait a number of frames first. You can use a TimedEvent component for this:

1. If you start the conversation using a DialogueSystemTrigger, set it to OnUse.

2. Add a TimedEvent component. If the SaveSystem's Frames To Wait Before Apply Data is 1, then set Mode to Frames and set Frames to 2. Configure OnTimeReached() to call the DialogueSystemTrigger's OnUse method.
Post Reply