Tutorial: Nested Dialogue Questions

From Stardew Modding Wiki
Jump to navigation Jump to search


Introduction

This tutorial is intended to teach you how to expand on the use of questions in dialogue by nesting one (or more) question inside another. You can also think of it as adding follow-up questions within one dialogue interaction. If you're not sure what I mean by that, read on! (And if you can think of a better way to describe it, feel free to edit this page to add your description or get in touch with me on the Stardew Valley Discord Server to let me know.)

Warning: this tutorial assumes you already understand how basic questions (using $q, not $y) work. If you're not familiar with them, this page probably won't make much sense to you. I suggest you head to the official wiki and read up on them.

Tutorial written by Abagaianye on 6th September 2024. This tutorial is up to date for Stardew Valley version 1.6.8.

Format

The first question in a nested question setup is written mostly as normal. The only difference is that in at least one reaction (response from the NPC to the player's choice of answer to the question) text, you write the dialogue command for the second question.

My examples don't include friendship point changes but they work as normal. Be aware that players will gain or lose friendship from each response they can choose where friendship point change is defined (e.g., if question 1 answer 1 gives 100 friendship and question 2 answer 2 gives 100 friendship, the player will gain 200 friendship from the interaction if they choose those options).

// Write your first question as normal
"Mon": "$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Question 1 text.
		#$r Q1_response_ID1 0 Q1_reaction1#Question 1 answer 1 text.
		#$r Q1_response_ID2 0 Q1_reaction2#Question 1 answer 2 text.",
// Reaction 1 does not have another question as a followup - it is written as normal
"Q1_reaction1": "Reaction 1 text in reply to Question 1 answer 1. Does not lead to a followup question. Ends dialogue.",
// Reaction 2 contains the second question. The question itself is written as normal - only the dialogue key is different.
"Q1_reaction2": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Question 2 text.
				#$r Q2_response_ID1 0 Q2_reaction1#Question 2 answer 1 text.
				#$r Q2_response_ID2 0 Q2_reaction2#Question 2 answer 2 text.",
// Second question's reaction 1 doesn't contain a question
"Q2_reaction1": "Reaction 1 text in reply to Question 2 answer 1. Ends dialogue.",
// Second question's reaction 2 doesn't contain a question either
"Q2_reaction2": "Reaction 2 text in reply to Question 2 answer 2. Ends dialogue.",
// Fallback for question 1. Next time the player talks to the NPC on a Monday and this dialogue triggers again, the fallback will play instead of the entire question repeating.
"Q1_fallback": "Fallback text for Q1 - this will play as long as Q1 has been asked before regardless of what response was chosen.",
// Fallback for question 2. This will never play because Q1_fallback takes precedence.
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",

Note: there are many variations in writing nested questions, including checking for the nested question response IDs in the fallback, nesting multiple questions in a row (depth), nesting questions in multiple answers to one question (breadth), playing the question again instead of using the fallback, and more. See below for examples of some.

Example

This example is identical to the format shown above but with "real" dialogue instead of explanatory placeholders.

"Mon": "$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
"Q1_reaction2": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Great! Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q2_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
"Q1_fallback": "Hmm, I think it might be time for another fishing day soon.",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",

Variations

Variations are all written using the fishing example.

You can use some variations together (e.g., multi-level nested questions with no fallback, or multiple single-level questions with multi-level nested questions for exponentially larger question trees).

This is not a full list of every way that you can vary your nested questions. If you find a way that you think is worth adding to this page, please either let me know or feel free to add it yourself.

Fallback to check Q1 and Q2 responses

What if you want to customise your fallback dialogue depending on what answer the player chose the first time they triggered the dialogue? You can nest $p commands too!

The following example will directly check whether Question 1 Answer 1 or Question 2 Answer 1 were chosen, and will indirectly check whether Question 2 Answer 2 was chosen. It doesn't check if Question 1 Answer 2 was chosen, as that just leads to Question 2, but you could modify this to check for that instead if you wanted to.

Note: You can have a nested $p fallback for non-nested questions as well if you have questions with more than two answers.

"Mon": "$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
"Q1_reaction2": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Great! Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q2_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
// The line below is the one to be changed for this variation. The rest of the lines are the same as the initial example.
"Q1_fallback": "$p Q1_response_ID1#You missed out on some great fishing, @.|$p Q2_response_ID1#That was such a great beach fishing trip! We should go again.|We should dress even more warmly next time we go on a mountain fishing trip!",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",

No fallback

If you would like your nested questions to replay every time the player triggers this particular dialogue line again there are two approaches:

  1. Remove the response IDs from the $q sections, or
  2. Use a different response ID in the $q sections to the one(s) you use in the $r sections

I'm going to show you how to do the first as I think it's cleaner. There might be benefits to taking the second approach instead but I've not yet found any.

Do NOT ever remove response IDs from the $r sections unless you want to break your question and possibly force your player into a neverending question loop.

Note: You can remove the $q response ID for normal questions as well. The advantage of doing it over using $y for non-nested questions is that you can add/remove friendship points. You can also use $p in other dialogue lines to check if a response ID in the question has been chosen before.

// I have removed "Q1_response_ID1/Q1_response_ID2" from the $q line below. This will make Q1 repeat.
"Mon": "$q Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
// I have also removed "Q2_response_ID1/Q2_response_ID2" from the $q line below. This will make Q2 repeat. If you don't do this, Q2_fallback will play instead the next time the player triggers this dialogue.
"Q1_reaction2": "$q Q2_fallback#Great! Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q2_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
"Q1_fallback": "Fallback text for Q1 - will never be seen because Q1 has no response ID.",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q2 has no response ID.",

Fallback to Q2_fallback

Do you want Question 1 to repeat if the dialogue is triggered again, but choosing the answer that leads to Question 2 goes to the Question 2 fallback instead of repeating Question 2?

Note: This variation is specific to nested questions.

// I have removed "Q1_response_ID1/Q1_response_ID2" from the $q line below. This will make Q1 repeat when the dialogue is triggered again.
"Mon": "$q Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
// I have not removed the response IDs from question 2. The second (or more) time this dialogue is triggered, Q2_fallback will play instead of Q2.
"Q1_reaction2": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Great! Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q2_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
"Q1_fallback": "Fallback text for Q1 - will never be seen because Q1 has no response ID.",
"Q2_fallback": "Great! I had so much fun fishing with you last time - I can't wait to go again.",

Multi-level nesting (depth)

You're not limited to nesting one single question inside another one. You can keep going!

You can use the technique of nesting $p commands to tailor your fallback responses to as many questions as you want to nest as long as you keep giving your nested questions unique response IDs.

Note: This variation is specific to nested questions.

"Mon": "$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
"Q1_reaction2": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Great! Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
// Replace Question 2 Reaction 2's text with the third question
"Q2_reaction2": "$q Q3_response_ID1/Q3_response_ID2 Q3_fallback#It might be cold in the morning up there. Should we go in the afternoon instead?
				#$r Q3_response_ID1 0 Q3_reaction1#No, we'll miss out on the best fish.
				#$r Q3_response_ID2 0 Q3_reaction2#Yeah, I don't want to get cold.",
"Q3_reaction1": "Wow, you're dedicated. Okay, morning in the mountains it is!",
"Q3_reaction2": "Okay, should we meet near Robin and Demetrius's house around 1pm?",
"Q1_fallback": "Hmm, I think it might be time for another fishing day soon.",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",
"Q3_fallback": "Fallback text for Q3 - will never be seen because Q1 has response IDs defined.",

Multiple nested questions at a single level (breadth)

You're also not limited to nesting a question inside one answer. You can nest a question inside every answer at a single level, if you like.

You can use the technique of nesting $p commands to tailor your fallback responses to as many questions as you want to nest as long as you keep giving your nested questions unique response IDs.

Note: This variation is specific to nested questions.

"Mon": "$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
// Replace the Question 1 reaction 1 text with a question
"Q1_reaction1": "$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Aww, why not?
				#$r Q2_response_ID1 0 Q2_reaction1#I don't like fishing.
				#$r Q2_response_ID2 0 Q2_reaction2#I don't like you.",
"Q2_reaction1": "Well, I guess that's understandable. Maybe another day we could do something you do like?",
"Q2_reaction2": "Wow, that's rude!",
// Question 1 reaction 2 still leads to the original question from the first example on this page
"Q1_reaction2": "$q Q3_response_ID1/Q3_response_ID2 Q3_fallback#Great! Where should we go?
				#$r Q3_response_ID1 0 Q3_reaction1#Let's go to the beach.
				#$r Q3_response_ID2 0 Q3_reaction2#I want to go to the mountains.",
"Q3_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q3_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
"Q1_fallback": "Hmm, I think it might be time for another fishing day soon.",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",
"Q3_fallback": "Fallback text for Q3 - will never be seen because Q1 has response IDs defined.",

Text before the question command

You can have the NPC say something before starting the question text - at any level of question - by using a # between the preceding text and the $q command.

Note: This applies to non-nested questions as well.

// I have added text and then a # before the $q for Question 1
"Mon": "Hi @, how are you doing?#$q Q1_response_ID1/Q1_response_ID2 Q1_fallback#Do you want to go fishing with me tomorrow?.
		#$r Q1_response_ID1 0 Q1_reaction1#No thanks.
		#$r Q1_response_ID2 0 Q1_reaction2#Sure!",
"Q1_reaction1": "Oh, okay. Well, maybe I'll see you around later. Bye!",
// I have added text and then a # before the $q for Question 2 as well
"Q1_reaction2": "You do want to? Great!#$q Q2_response_ID1/Q2_response_ID2 Q2_fallback#Where should we go?.
				#$r Q2_response_ID1 0 Q2_reaction1#Let's go to the beach.
				#$r Q2_response_ID2 0 Q2_reaction2#I want to go to the mountains.",
"Q2_reaction1": "Great! I'll meet you there tomorrow morning. I might collect some shells, too.",
"Q2_reaction2": "Great! I'll meet you there tomorrow morning. Dress warm - it'll be cold up there!",
"Q1_fallback": "Hmm, I think it might be time for another fishing day soon.",
"Q2_fallback": "Fallback text for Q2 - will never be seen because Q1 has response IDs defined.",