XML Import/Export

Announcements, support questions, and discussion for Quest Machine.
Post Reply
Gandoff
Posts: 20
Joined: Mon Jan 01, 2018 7:13 pm

XML Import/Export

Post by Gandoff »

Does Quest Machine support the importing and exporting of quests via XML?
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: XML Import/Export

Post by Tony Li »

Not yet. You can import and export Text Tables to CSV format (e.g., Excel).

With a bit of coding, you can import and export quests to JSON using QuestProxy, but there currently isn't a script-free editor option.
Gandoff
Posts: 20
Joined: Mon Jan 01, 2018 7:13 pm

Re: XML Import/Export

Post by Gandoff »

Okay. I was looking to import something like the attached XML file. It contains your Find Coins example quest. Please note this is not perfected yet. After I import this, I thought I would use something like the code you provided to create a script from C# to load this data in and complete the process.

Code: Select all

<?xml version="1.0"?>
<quest xmlns="<namespaceURLhere>">
	<questId>FindCoins</questId>
	<questTitle>Find Coins</questTitle>
	<questIcon></questIcon>
	<isTrackable>true</isTrackable>
	<showInTrackHUD>true</showInTrackHUD>
	<questGiver>villager</questGiver>
	<questGroup>Farming</questGroup>
	<questState state="Offer">
		<text state="OfferText">Orcs stole my gold and hid it in containers around the village! Will you please find 3 coins so I can buy seeds next season?</text>
	</questState>
	<questState state="Active">
		<text state="Dialogue">Find Coins</text>
		<text state="Journal">Find Coins</text>
		<text state="HUD">Find Coins</text>
	</questState>
	<questState state="Successful">
		<text state="Dialogue">Find Coins</text>
		<text state="Journal">Find Coins</text>
	</questState>
	<counter>
		<counterName>coins</counterName>
		<counterInitVal>0</counterInitVal>
		<counterMin>0</counterMin>
		<counterMax>3</counterMax>
		<counterRndInitVal>false<counterRndInitVal>
		<counterUpdateMode mode="Messages">
			<me_op_cmd>Get</me_op_cmd>
			<me_op_parm>Coin</me_op_parm>
			<me_operation mode="ModifyByLiteralValue">
				<me_increment>1</me_increment>
			</me_operation>
		</counterUpdateMode>
	</counter>
	<questNode>
		<nodeId>Condition1</nodeId>
		<nodeName>Find Coins</nodeName>
		<nodeType>Conditional</nodeType>
		<nodeParentId>Start</nodeParentId>
		<questNodeCondition>
			<counterName>coins</counterName>
			<countValCondMode>AtLeast</countValCondMode>
			<counterMax>3</counterMax>
		<questNodeCondition>
		<questState state="Active">
			<text state="Dialogue">Please find my money.</text>
			<text state="Journal">Find the farmer's coins hidden in containers.</text>
			<text state="HUD">{#coins}/3 Coins</text>
		</questState>
	</questNode>
	<questNode>
		<nodeId>ReturnNode</nodeId>
		<nodeName>Found Coins</nodeName>
		<nodeType>Discuss</nodeType>
		<nodeParentId>Condition1</nodeParentId>
		<questState state="Active">
			<text state="Dialogue">Thanks for finding my coins!</text>
			<text state="Journal">Return to the villager.</text>
			<text state="HUD">Return to villager</text>
		</questState>
		<questState state="True">
			<text state="Dialogue">Thanks for finding my coins!</text>
			<text state="Journal">You found the farmer's coins and saved the farm!</text>
		</questState>
		<questNodeAction state="Active">
			<actionType>ActionAlert</actionType>
			<questText state="Active">
				<text state="Active">Return to villager</text>
			</questText>
		</questNodeAction>
		<questNodeAction state="Active">
			<actionType>Indicator</actionType>
			<questStateIndicator>Talk</questStateIndicator>
		</questNodeAction>
	</questNode>
	<questNode>
		<nodeId>Success</nodeId>
		<nodeName>Success</nodeName>
		<nodeType>Success</nodeType>
		<nodeParentId>ReturnNode</nodeParentId>
	</questNode>
</quest>
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: XML Import/Export

Post by Tony Li »

That should work!

I haven't had time to implement anything similar, but I'm also taking my time evaluating options.

Raw XML is difficult to work with. Many devs who use the Dialogue System for Unity write their dialogue in third party software like articy:draft and Chat Mapper, although the vast majority use the Dialogue System's built-in Dialogue Editor window in Unity. I'm considering support for importing articy:draft XML into Quest Machine, but articy:draft isn't great for defining complex quests in a compact way. (It and Chat Mapper are really good for writing dialogue, though.)

I'm probably going to use a custom text or CSV format that should be more compact and easier to edit than raw XML. Please let me know how it goes with your XML script and your whole XML editing process.
Gandoff
Posts: 20
Joined: Mon Jan 01, 2018 7:13 pm

Re: XML Import/Export

Post by Gandoff »

I am trying to create QuestNodes and link them together as parent/child.

How do I find the parent QuestNode by using a passed in string id?

As an example from the "Find Coins" example, how do I get the QuestNode reference associated with the "id=Start" node to add as parent to the "Condition1" node creation parameters. Then I need to use the "id=Condition1" string to find the parent Questnode for the "ReturnNode", etc.

So, to sum this up, I need a method to return the QuestNode given its' string id as the parameter to the method.
Example:
QuestNode parentQN = FindQuestNodeByID("Condition1"); // returns the parent QuestNode to be used for the ReturnNode

NOTE: I will get the QuestNode string ids from the XML file.
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: XML Import/Export

Post by Tony Li »

Hi,

If you use QuestBuilder, get the start node using QuestBuilder.GetStartNode().

And if you continue to use QuestBuilder's AddXNode methods, hold onto the parent and pass it along as you add each node:

Code: Select all

// [START]:
QuestNode startNode = questBuilder.GetStartNode();

// [START] --> [Condition1]:
QuestNode conditionNode = questBuilder.AddConditionNode(startNode, "Condition1", "My Condition", ConditionCountMode.All);

// [START] --> [Condition1] --> [SUCCESS]:
QuestNode successNode = questBuilder.AddSuccessNode(conditionNode);
If you don't use QuestBuilder but you have a reference to the Quest object, use Quest.GetNode() to get a specific node:

Code: Select all

QuestNode startNode = quest.GetNode("Start");
However, you'll have to keep track of parents yourself by traversing nodes' children. The easiest way to access a node's children is the QuestNode.childList property. If you've added nodes to a quest, you need to call Quest.SetRuntimeReferences() to set up childList first:

Code: Select all

quest.SetRuntimeReferences(); // Set up childList.
foreach (var childNode in quest.GetStartNode().childList)
{
    Debug.Log("Child: " + childNode.id);
}
There is a parentList property that was reserved for the upcoming version 1.0.2. It's not implemented in the current 1.0.1 release. If you'd like an advance version of 1.0.2, let me know. I'm finishing work for the day, but I can get it to you tomorrow.
Gandoff
Posts: 20
Joined: Mon Jan 01, 2018 7:13 pm

Re: XML Import/Export

Post by Gandoff »

Great, thanks for the help. I am almost there.

The only thing I am seeing wrong now is the icon for the quest is not showing up.
My XML has a name of a sprite (icon). I am attempting to load it via a C# statement like:

reader.Value (where this pulls from the XML file a string such as "UI/coin")
quest.questIcon = Resources.Load(reader.Value) as Sprite;

NOTE: the quest variable is a class of mine not Quest Machine's quest class. The questIcon is defined as:
public Sprite questIcon;
in my quest class
I get a null sprite. I have added a copy of the coin sprite from the demo into Assets/Resources/UI/coin
Any help would be greatly appreciated!
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: XML Import/Export

Post by Tony Li »

Hi,

Are you sure that "Resources.Load(reader.Value)" is returning a valid Sprite?

You could try something like this:

Code: Select all

var sprite = Resources<Sprite>.Load(reader.Value);
if (sprite == null) {
    Debug.LogError("Failed to load sprite UI/coin!");
} else {
    quest.questIcon = sprite;
}
Gandoff
Posts: 20
Joined: Mon Jan 01, 2018 7:13 pm

Re: XML Import/Export

Post by Gandoff »

I got it to work using the following statement:

quest.questIcon = Resources.Load(reader.Value, typeof(Sprite)) as Sprite;

That worked for me. Thanks for the help. I can now load the Find Coins quest via XML.

The major problem with this however, is that it does not work using WebGL. All I get is a black screen and the browser continues to announce the web page is taking too long do you want to continue waiting?
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: XML Import/Export

Post by Tony Li »

Unity's Debugging and troubleshooting WebGL builds page has some good tips. It sounds like it might have gotten into some kind of infinite loop. Not all file access methods are available in WebGL. Is your code making any assumptions that certain method calls will succeed, when in fact they might fail in WebGL?

If you don't see anything like that in your code, then a good first step is to:

1. Tick the Development Build checkbox.

2. Set Enable Exceptions to Full with stacktrace.

3. Bump up the WebGL Memory Size to 384 or more.

Then rebuild and play. Open your browser's Javascript console to see the debug log.
Post Reply