Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to expand variables inside of dialog #25

Closed
Hexalotl opened this issue Feb 25, 2016 · 26 comments
Closed

Add the ability to expand variables inside of dialog #25

Hexalotl opened this issue Feb 25, 2016 · 26 comments
Assignees
Milestone

Comments

@Hexalotl
Copy link

It would be really convenient if variables inside of dialog were replaced with their values. This would allow the dialog to be a lot more dynamic.

Some examples:
"$player_name is pretty cool!" would change to "Samus is pretty cool!"
"You have $gold_in_bank gold in your account" would change to "You have 50 gold in your account".

@desplesda
Copy link
Collaborator

This is something I'd like to add. It needs two things to happen first: variables need to be able to store values other than numbers, and we need to figure out how localisation works, since this proposed feature would be affected by it.

On 26 Feb 2016, at 10:26 AM, Dynameter notifications@github.com wrote:

It would be really convenient if variables inside of dialog were replaced with their values. This would allow the dialog to be a lot more dynamic.

Some examples:
"$player_name is pretty cool!" would change to "Samus is pretty cool!"
"You have $gold_in_bank gold in your account" would change to "You have 50 gold in your account".


Reply to this email directly or view it on GitHub.

@konistehrad
Copy link
Contributor

I know I'm coming in doe-eyed and fresh faced, but I've been reviewing the code and I think there's a lot of potential here if the VariableStorage interface worked with the Value class in Parser.cs. It already holds a good deal of information about what the "real" backing-type is, and can be modified to deal with the JS-like semantics that Twee code wants to work with. It's very good at coercing multiple input types into proper backing (great for deserialization), and can be consumed for serialization easily if the type property and Enum were made public.

I'm noodling around with a concept like this in a branch. Didn't know if there were serious potholes ahead if I continued with this approach.

Thanks again!

@desplesda
Copy link
Collaborator

Right. If variables are going to store any additional types besides floats, VariableStorage and Value need to work together a little better. I'd be very interested in looking at a pull request 😁

There's really only one specific thing to keep in mind: existing games will need to not be broken by changes. So you'll need to do it in a backwards-compatible way.

@desplesda
Copy link
Collaborator

Any work on this will likely touch on #33 as well.

@konistehrad
Copy link
Contributor

Yeah, in my efforts in my branch I marked Get/SetNumber as obsolete, and created a very simple abstract class that coerces the float's into Value's and vice versa. If deserialization routines leverage these methods, everything should Just Work™, but the possibility of breakage is very real if the deserialization routines don't handle this case properly.

There's also the matter of expanding the VariableStorage interface, which is always a Dastardly Change ... if this package follows semver this may make a good transition from 0.x to 1.x, but that's certainly not my call to make. I'm going to try to have a PR up for review in a couple days, which hopefully will help the decision making process.

Thanks again! (Y'all are so fast at responding, haha).

@desplesda
Copy link
Collaborator

Yeah, semver was my intention for this, but I'm more comfortable with making changes to the public API in the 0.x releases than I will be in 1.x releases. If it doesn't break existing games, and minimises any additional burden on new developers, I'll likely be OK with it.

@konistehrad
Copy link
Contributor

In retrospect, if existing games leverage the VariableStorageBehaviour Unity class we can safely add Get/SetValue methods on that, which consume Get/SetFloat instead of the opposite. It would preserve the Unity side, anyway, at least on paper.

Also, it was my intention to provide very basic serialization / deserialization routines using .NET's XML serializer, which hopefully should allow new developers to onboard a little easier. We'll see how it shakes out, haha.

@desplesda
Copy link
Collaborator

Yeah, that sounds good.

I'm hesitant to introduce serialisation/deserialisation into Yarn Spinner itself, because it's designed to be a single piece of the puzzle that fits alongside existing elements. Yarn Spinner doesn't and shouldn't care about how you save your variables - it wants you to handle that yourself, in your own way.

If you do introduce your own serialisation infrastructure, I strongly suggest making it an example script and keeping it in Unity-space. It's a really good idea to make it easier for new developers! But game developers will likely need to save lots of additional data besides the variables in their dialogue system. If that gets serialised separately, we're merely solving one problem while introducing new ones.

(If this was your intention all along: ignore all of the above 😁)

@konistehrad
Copy link
Contributor

Ha! Nah that's great direction. I'll ensure that user-facing stuff stays user-facing and sticks around as example code in Unity. Thanks again!

@desplesda
Copy link
Collaborator

We've been talking a lot about storing different types in variables in this issue, but this issue is actually about string expansion in lines of Yarn. So I've created a new issue specifically for the variable storage topic at #36 - please continue discussion related to that there! 👍

This issue will remain open until string expansion is sorted.

@desplesda
Copy link
Collaborator

#36 is now done; variables can now store strings. This was a pre-requisite for this issue.

@lainfarlight
Copy link

Are there general plans with regards to handling localisation? I know that was another pre-requisite for this issue and I was intending to look in to string expansion more soon, since the variable type stuff just went in.

@desplesda
Copy link
Collaborator

I’m hoping to post some notes about the general plan today. Had a chat with Ron Gilbert (!!) about this very topic at GDC.

@lainfarlight
Copy link

That's awesome. Looking forward to reading them~

On 4/2/2016 2:27 PM, Jon Manning wrote:

I’m hoping to post some notes about the general plan today. Had a chat
with Ron Gilbert (!!) about this very topic at GDC.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#25 (comment)

@desplesda
Copy link
Collaborator

I'm proposing that we add syntax to Yarn that supports this. It would look like this:

He's going to [$method_of_destruction] the [$target] on [$day_of_week]!

Depending on the value of the variables $method_of_destruction, $target and $day_of_week, this line could be delivered to the client application as:

He's going to blow up the stadium on Wednesday!

In this line, the square brackets are delimiters; within these delimiters, a variable name is given.

I'm tempted to restrict this syntax to be variables only; the reasoning for this is that if we support arbitrary expressions, that means supporting functions, and if those functions return strings, Yarn has no way to determine what their possible values are, and therefore can't figure out if they need to be localised or not. This restriction can be lifted later, once this problem is solved.

I'd like to open this up for discussion. Anyone have any thoughts on how this could be better?

@lainfarlight
Copy link

In terms of my use case, I can't imagine needing more than the ability to expand variables, as I can just store function output in a variable before the line is output and get around the need for any inline function calls. So in the above proposed form, it certainly suits my needs.

@konistehrad
Copy link
Contributor

Yes to just variable expansion; heavy computation can be done in custom macro's that are invoked before usage, and that's probably where heavy computation belongs. Being the resident Twine-compatibility buzzkill I checked to see if twine has a variable expansion built in and it seems to use the <<print>> macro to accomplish this, so we're in the clear there!

Stylistically, I used ${varName} in htmlVN, cribbed almost wholly from Bash. I've never personally seen [$varName] variable expansion syntax, but I've got no technical objections. It'll tokenize the same either way!

@desplesda
Copy link
Collaborator

My reasoning for using square brackets [ instead of braces { is to differentiate them from line codes (#39), which use braces.

Additionally, using square braces likens them to their use in print, to represent an inferred or replaced word: "She [said] she hadn't done [the refuelling] yet."

@TheSabotender
Copy link

TheSabotender commented Jun 21, 2016

A temporary solution to those who need this ASAP:
In Yarn, fill out your dialog as @desplesda recommends "Hey there [$charname], how are you?"
Then, in your DialogueUIBehaviour script, add the following function:

string CheckVars (string input)
    {
        string output = string.Empty;
        bool checkingVar = false;
        string currentVar = string.Empty;

        int index = 0;
        while (index < input.Length) {
            if (input [index] == '[') {
                checkingVar = true;
                currentVar = string.Empty;
            } else if (input [index] == ']') {
                checkingVar = false;
                output += ParseVariable(currentVar);
                currentVar = string.Empty;
            } else if (checkingVar) {
                currentVar += input [index];
            } else {
                output += input[index];
            }
            index += 1;
        }

        return output;
    }

    string ParseVariable (string varName)
    {
        //Check YarnSpinner's variable storage first
        if (variableStorage.GetValue (varName) != Yarn.Value.NULL) {
            return variableStorage.GetValue (varName).AsString;
        }

        //Handle other variables here
        if(varName == "$time") {
            return Time.time.ToString();
        }

        //If no variables are found, return the variable name
        return varName;
    }

Finally, in the RunLine function, make sure to replace all instances of
"line.text" with CheckVars(line.text)

This way the UI handles the conversion of variables, not the best solution, especially when localization becomes relevant, but it works for now!

For example, in my dialog I have "Hey there [$charName_1]", and in my "Handle other variables" section, I have:

 //Handle other variables here
 if (varName.Contains ("_")) {
     string[] split = varName.Split ('_');
     if (split [0] == "$charName") {
         int charIndex = int.Parse(split[1]);
         return CharacterManager.instance.characters[charIndex].GetName();
     }
 }

@rmill019
Copy link

Would that be in the ExampleDialogueUI script? Or in the DialogueRunner script, where the abstract class of DialogueUIBehaviour is defined

@ka-de
Copy link

ka-de commented Nov 28, 2017

@rmill019 The modification by @TheSabotender goes into ExampleDialogueUI.cs

@rmill019
Copy link

@Kadelam Thank you. I was able to get it to work.

@rmill019
Copy link

Our current project is attempting to be able to call variables in responses as well. By any chance does anybody here know if someone has figured out a quick fix to incorporate this?

@McJones
Copy link
Collaborator

McJones commented Jan 24, 2018

Sorry, what do you mean but call variables in response?

@DongerZone
Copy link

Just a heads up for everyone, in order to use the function above you also need to add a public variable that references your current Variable Storage script

@sawalls sawalls mentioned this issue May 10, 2020
6 tasks
@desplesda
Copy link
Collaborator

This feature shipped in v1.1, so I'm closing this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants