ORK integration

Announcements, support questions, and discussion for Quest Machine.
dlevel
Posts: 181
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

Seems like we are in the right track :)

1 player with finished quests:

QuestJournalForORKWithVerify is restoring the quest journal.
QuestJournalForORKWithVerify is making a list of bad quests and completed quests.
QuestJournalForORKWithVerify: quest is completed: Kill 20 Rotten Dins 05fc1c92-f31f-4554-8d0b-ec2e37326818
QuestJournalForORKWithVerify: quest is completed: Kill 20 Werewolfs Tyr 54489a36-65e7-4c1f-bd4b-960d1a72d958
QuestJournalForORKWithVerify removing completed quest Kill 20 Rotten Dins 05fc1c92-f31f-4554-8d0b-ec2e37326818
QuestJournalForORKWithVerify removing completed quest Kill 20 Werewolfs Tyr 54489a36-65e7-4c1f-bd4b-960d1a72d958

1 player with bad quests:

QuestJournalForORKWithVerify is restoring the quest journal.
QuestJournalForORKWithVerify is making a list of bad quests and completed quests.
QuestJournalForORKWithVerify: quest is bad: CraftingQuest
QuestJournalForORKWithVerify: quest is bad: DragonMountQuest
QuestJournalForORKWithVerify: quest is bad: RuinsAroundZargat
QuestJournalForORKWithVerify adding fresh copy of bad quest CraftingQuest
QuestJournalForORKWithVerify adding fresh copy of bad quest DragonMountQuest
QuestJournalForORKWithVerify adding fresh copy of bad quest RuinsAroundZargat


another player with bad quests that appear on QuestJournalForORKWithVerify but not on the actual Journal at all (new bad quest just found out about it):

QuestJournalForORKWithVerify is restoring the quest journal.
QuestJournalForORKWithVerify is making a list of bad quests and completed quests.
QuestJournalForORKWithVerify: quest is completed: Kill 20 Dark Wolves 47341b41-0cb2-462a-991a-7b6c34a5268e
QuestJournalForORKWithVerify: quest is completed: Kill 20 Rotten Dins a6739ba0-fb85-445a-8090-dd91b32fceea
QuestJournalForORKWithVerify: quest is bad: RuinsAroundMooria
QuestJournalForORKWithVerify removing completed quest Kill 20 Dark Wolves 47341b41-0cb2-462a-991a-7b6c34a5268e
QuestJournalForORKWithVerify removing completed quest Kill 20 Rotten Dins a6739ba0-fb85-445a-8090-dd91b32fceea
QuestJournalForORKWithVerify adding fresh copy of bad quest RuinsAroundMooria

And it restored bad quests fine it seems!
User avatar
Tony Li
Posts: 22083
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Does everything seem to be working now? Or are there cases that still don't work?
dlevel
Posts: 181
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

Doing a testing build for testers and will come back:)
dlevel
Posts: 181
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

ok thank you again, it seems this works! Now I got some questions if you have time about saving/loading.

Here is a save of a player that has a lot of quests (36), only the 2 lines that has the quests that is. Does it make sense to have so many characters for the save? its like 120kb for the first line, and 55kb for the 2nd. thats more than 170k characters, what are all those numbers in there? :D

Also I see that it tries to load the quests 36 times when player enters the game, are the quests load the whole quest save for each time they are loading? since it seems that I have 36 quests and 36 times this lines (36x175kb are loaded)? If yes can this be changed? There is like 9mb data in 1" for this player to load the quests which seems too excessive.

https://we.tl/t-laieBrbmUU
Thank you
User avatar
Tony Li
Posts: 22083
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi,

The first line, which starts with "<savedgamedata>", was created by the ORKSavedGameData component.

The second line, which starts with "<data>", was created by the QuestJournalForORK(WithVerify) component.

Once you tick Allow ORKQuestMachineSaveData To Save, the second line will disappear from subsequent saved games.

The first line's data contains Quest Machine's saved game data. Notice that each quest giver has saved its info. If you don't need to save some quest givers' info, in particular procgen quest givers, you can untick their Save Settings > Include In Saved Game Data checkboxes. Here's a trimmed excerpt of line 1, which I ran through a JSON prettifier:

Code: Select all

{
   "m_version":0,
   "m_sceneName":"AGF_Demoopen",
   "m_list":[
      {
         "key":"Quest Giver Event New Era",
         "sceneIndex":-1,
         "data":"{"staticQuestIds":["ReachLevel50","ReachLevel60","TradersCertificate5",...],"staticQuestData":[{"bytes":[0,3,0,...0]}],"proceduralQuests":[],"deletedStaticQuests":["TradersCertificate1","ReachLevel10","ClearAMediumDungeon1",...]}"
      },
      {
         "key":"AligrenRuinsQuestGiver",
         "sceneIndex":-1,
         "data":"{"staticQuestIds":["RuinsAroundAligren"],"staticQuestData":[{"bytes":[0,3,0,...]}],"proceduralQuests":[],"deletedStaticQuests":[]}"
      },
      ...
dlevel
Posts: 181
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

QuestJournalForORKWithVerify the latest one you told me to copy doesn't have the option to use ORKQuestMachineSaveData, also what about the game loading the same things 36 times? (as many as the quests), it needs to pull all the data 36 times for all quests?

Code: Select all

using System.Collections.Generic;
using UnityEngine;
using ORKFramework;

namespace PixelCrushers.QuestMachine.ORKSupport
{
    public class QuestJournalForORKWithVerify : QuestJournalForORK
    {

        public override void LoadGame(DataObject data)
        {
            // If the saved game doesn't have QuestJournalForORK data,
            // then we know that it's saved through ORKQuestMachineSaveData,
            // and we don't need to do anything.
            if (data == null)
            {
                Debug.Log("QuestJournalForORKWithVerify has no saved data. Exiting.");
                return;
            }

            // If QuestJournalForORK has saved data, we use it to restore
            // the player's quest journal, and then we remove "bad" quests.

            // First, restore the quests.
            Debug.Log("QuestJournalForORKWithVerify is restoring the quest journal.");
            base.LoadGame(data);

            // Then make a list of bad quests, which are quests whose Start
            // nodes aren't in the True state.
            Debug.Log("QuestJournalForORKWithVerify is making a list of bad quests and completed quests.");
            var badQuests = new List<Quest>();
            var completedQuests = new List<Quest>();
            foreach (var quest in questList)
            {
                if (quest == null) continue;
                if (quest.GetState() == QuestState.Successful)
                {
                    Debug.Log($"QuestJournalForORKWithVerify: quest is completed: {quest.id}");
                    completedQuests.Add(quest);
                }
                else if (quest.startNode == null ||
                    quest.startNode.GetState() != QuestNodeState.True)
                {
                    Debug.Log($"QuestJournalForORKWithVerify: quest is bad: {quest.id}");
                    badQuests.Add(quest);
                }
            }

            // Remove completed quests:
            foreach (var completedQuest in completedQuests)
            {
                Debug.Log($"QuestJournalForORKWithVerify removing completed quest {completedQuest.id}");
                DeleteQuest(completedQuest);
            }

            // Finally, replace the bad quests in the journal.
            foreach (var badQuest in badQuests)
            {
                Debug.Log($"QuestJournalForORKWithVerify adding fresh copy of bad quest {badQuest.id}");
                var questAsset = badQuest.originalAsset;
                DeleteQuest(badQuest);
                var questInstance = questAsset.Clone();
                var questerTextInfo = new QuestParticipantTextInfo(id, displayName, image, null);
                questInstance.AssignQuester(questerTextInfo);
                questInstance.timesAccepted = 1;
                deletedStaticQuests.Remove(StringField.GetStringValue(questInstance.id));
                AddQuest(questInstance);
                questInstance.SetState(QuestState.Active);
            }
            QuestMachineMessages.RefreshUIs(this);
        }
    }

}
User avatar
Tony Li
Posts: 22083
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi,

If ORK is functioning properly, then to my knowledge it should only pull data once for each QuestJournalForORK or QuestGiverForORK, plus once for ORKQuestMachineSaveData.

Do you have 36 quest givers perhaps? If a quest giver doesn't need to save its info, you can replace its QuestGiverForORK component with a QuestGiver component. This way it won't hook into the save system at all. (If the NPC has a QuestGiverForORK whose "Allow ORK Quest Machine Save Data To Save" checkbox is ticked, it will save/load an empty ORK data object, but ORK will still store and retrieve it.)

To answer your other question, all those numbers are the binary-to-JSON representation of the minimum data required to save handwritten (non-procgen) quests: things like quest states, counter values, etc.
dlevel
Posts: 181
Joined: Wed Nov 16, 2016 6:17 pm

Re: ORK integration

Post by dlevel »

Ok thank you, will make some tests



1) There is one more bugged quest we don't cover in the script you made, the duplicates, some players have the same quest twice. Should remove 1 of the instances (or both and add a fresh one)
2) Enabled Allow ORK Quest Machine save to everything (including QuestGiverForORKWithVerify) removes this issue, but no quests are loaded to the player
3) Removing the Allow ORK Quest Machine save from QuestGiverForORKWithVerify brings back the quests for the player and the times the quests added are reduced a lot the 122k line (down to 5 times from 36 before) but the 51kb line is still 36 times there. So it seems the Quest Journal is calling all these lines somehow.

Reverified, the moment I duplicate the player in runtime, it loads all quests 34 times in 1 frame (that many are the quests in the Journal)


I think I found the issue, don't take any action trying to verify, seems it's my fault


Here is the issue, I had an event on the QuestListener so I can get the state of the quests, and then saving the game, which triggered 34 times on starting the game, will adjust this to not cause this issue.

Again thank you for your help, and if we can have no1 fix as well (duplicate bugged quests) would be great.
User avatar
Tony Li
Posts: 22083
Joined: Thu Jul 18, 2013 1:27 pm

Re: ORK integration

Post by Tony Li »

Hi,

Try this version:

Code: Select all

using System.Collections.Generic;
using UnityEngine;
using ORKFramework;

namespace PixelCrushers.QuestMachine.ORKSupport
{
    public class QuestJournalForORKWithVerify : QuestJournalForORK
    {

        public override string GetSaveKey()
        {
            return "data";
        }

        public override void LoadGame(DataObject data)
        {
            // If the saved game doesn't have QuestJournalForORK data,
            // then we know that it's saved through ORKQuestMachineSaveData,
            // and we don't need to do anything.
            if (data == null)
            {
                Debug.Log("QuestJournalForORKWithVerify has no saved data. Exiting.");
                return;
            }

            // If QuestJournalForORK has saved data, we use it to restore
            // the player's quest journal, and then we remove "bad" quests.

            // First, restore the quests.
            Debug.Log("QuestJournalForORKWithVerify is restoring the quest journal.");
            base.LoadGame(data);

            // Then make a list of bad quests, which are quests whose Start
            // nodes aren't in the True state, completed quests, and duplicate
            // quests.
            Debug.Log("QuestJournalForORKWithVerify is making a list of bad quests and completed quests.");
            var badQuests = new List<Quest>();
            var completedQuests = new List<Quest>();
            var duplicateQuests = new List<Quest>();
            var checkedQuests = new List<Quest>();
            foreach (var quest in questList)
            { 
                if (quest == null) continue;
                checkedQuests.Add(quest);
                if (quest.GetState() == QuestState.Successful)
                {
                    Debug.Log($"QuestJournalForORKWithVerify: quest is completed: {quest.id}");
                    completedQuests.Add(quest);
                }
                else if (quest.startNode == null ||
                    quest.startNode.GetState() != QuestNodeState.True)
                {
                    Debug.Log($"QuestJournalForORKWithVerify: quest is bad: {quest.id}");
                    badQuests.Add(quest);
                }
                else if (checkedQuests.Find(x => StringField.Equals(x.id, quest.id)) != null)
                {
                     Debug.Log($"QuestJournalForORKWithVerify: duplicate quest: {quest.id}");
                    duplicateQuests.Add(quest);
                }
            }

            // Remove completed quests:
            foreach (var completedQuest in completedQuests)
            {
                Debug.Log($"QuestJournalForORKWithVerify removing completed quest {completedQuest.id}");
                DeleteQuest(completedQuest);
            }

            // Remove duplicate quests:
            foreach (var duplicateQuest in duplicateQuests)
            {
                Debug.Log($"QuestJournalForORKWithVerify removing duplicate quest {duplicateQuest.id}");
                DeleteQuest(duplicateQuest);
            }

            // Finally, replace the bad quests in the journal.
            foreach (var badQuest in badQuests)
            {
                Debug.Log($"QuestJournalForORKWithVerify adding fresh copy of bad quest {badQuest.id}");
                var questAsset = badQuest.originalAsset;
                DeleteQuest(badQuest);
                var questInstance = questAsset.Clone();
                var questerTextInfo = new QuestParticipantTextInfo(id, displayName, image, null);
                questInstance.AssignQuester(questerTextInfo);
                questInstance.timesAccepted = 1;
                deletedStaticQuests.Remove(StringField.GetStringValue(questInstance.id));
                AddQuest(questInstance);
                questInstance.SetState(QuestState.Active);
            }
            QuestMachineMessages.RefreshUIs(this);
        }
    }

}
Post Reply