diff --git a/.gitignore b/.gitignore index 7e3309f30..15063cdaf 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ bin/ obj/ *.userprefs +### Visual Studio ### +.vs/ ### OSX ### .DS_Store @@ -84,3 +86,4 @@ GPATH GRTAGS GTAGS GSYMS +(??) diff --git a/.travis.yml b/.travis.yml index c793596c7..0a9722c0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,14 +27,14 @@ addons: script: - "./antlr.sh" - "./build.sh -bcuv" -#deploy: -# provider: releases -# api_key: -# secure: ppMWm5zS3NfplInwq+JdBBLFgTPVvpLrTeqcTdpHRBLtoiKHtfiPDVhvRKshu5qdbp+h1L0ZWTxfXdmOzYxdrXlLQkUAMFIlj7kY+hfzBcSnfA707dJapx6Q9LeJCy50JuDXEx+hPCjNAREz6+YP1Cb5FVwFoC3pu0FQ0Qg+86uUy4D3jZDMmjHIg0qN+sdwOf1xTmLJ37nuoDSpsUWx4MDMh/RP/7Uwz9lxYBw1XcWlddZzHesLj0HUuRmRSrk/4KNEQsYavH2U+vgPnRuWVITuB/Y2LqLE+pleNCt5NiqVvSHZgRTSYu4Jik7ivaNa+JuVjeAokJubRv1wUba3wlU25fUfzeBvm1bxGbF+7HofZSaaUvK28JP1e/LYR8EfwPy4L+yfasEGh5McTKjsdKKK+c8wrvR1EaPwNe7bPy0YOeHfxf2/aTR8PoEqPQdzLo2VIIMdqEvChiE7Z6X2WgPBxbGoBp5NOL3uRhE/9aAyMSIt/sYZvtSmbtxfK5qCEMP0j2cNRs0d91DaL9nsnEFYu9jrddwX68HgtWmt77MdGAYMz5vyQPQtJuKKATST3HkKDvWyoWcNgnF4xL0U0bOZZcBGilZDuvEAqSSyw7oCXTnbh0B+pCpo6NOaV4ks62klmAbaC3IPAOvajlgViB6sHsknixys/Z1VkQjI5YY= -# file: YarnSpinner/bin/Release/YarnSpinner.dll -# skip_cleanup: true -# on: -# tags: true +deploy: + provider: releases + api_key: + secure: ppMWm5zS3NfplInwq+JdBBLFgTPVvpLrTeqcTdpHRBLtoiKHtfiPDVhvRKshu5qdbp+h1L0ZWTxfXdmOzYxdrXlLQkUAMFIlj7kY+hfzBcSnfA707dJapx6Q9LeJCy50JuDXEx+hPCjNAREz6+YP1Cb5FVwFoC3pu0FQ0Qg+86uUy4D3jZDMmjHIg0qN+sdwOf1xTmLJ37nuoDSpsUWx4MDMh/RP/7Uwz9lxYBw1XcWlddZzHesLj0HUuRmRSrk/4KNEQsYavH2U+vgPnRuWVITuB/Y2LqLE+pleNCt5NiqVvSHZgRTSYu4Jik7ivaNa+JuVjeAokJubRv1wUba3wlU25fUfzeBvm1bxGbF+7HofZSaaUvK28JP1e/LYR8EfwPy4L+yfasEGh5McTKjsdKKK+c8wrvR1EaPwNe7bPy0YOeHfxf2/aTR8PoEqPQdzLo2VIIMdqEvChiE7Z6X2WgPBxbGoBp5NOL3uRhE/9aAyMSIt/sYZvtSmbtxfK5qCEMP0j2cNRs0d91DaL9nsnEFYu9jrddwX68HgtWmt77MdGAYMz5vyQPQtJuKKATST3HkKDvWyoWcNgnF4xL0U0bOZZcBGilZDuvEAqSSyw7oCXTnbh0B+pCpo6NOaV4ks62klmAbaC3IPAOvajlgViB6sHsknixys/Z1VkQjI5YY= + file: "$TRAVIS_BUILD_DIR/YarnSpinner/bin/Release/YarnSpinner.dll" + skip_cleanup: true + on: + tags: true after_success: - cd $TRAVIS_BUILD_DIR - chmod +x DeployDocumentation.sh diff --git a/Documentation/Doxyfile b/Documentation/Doxyfile index 96965c849..2ad1f7a55 100644 --- a/Documentation/Doxyfile +++ b/Documentation/Doxyfile @@ -790,7 +790,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = README.md LICENSE.md Documentation/YarnSpinner-Programming Unity YarnSpinner YarnSpinnerConsole YarnSpinnerTests +(??) # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/Documentation/YarnSpinner-Dialogue/Localization.md b/Documentation/YarnSpinner-Dialogue/Localization.md new file mode 100644 index 000000000..0321f1aa1 --- /dev/null +++ b/Documentation/YarnSpinner-Dialogue/Localization.md @@ -0,0 +1,20 @@ +# LOCALIZATION +Yarn Spinner provides tools to help convert your game in to any language you like. This is achieved by usage of the [YarnSpinnerConsole](../YarnSpinnerConsole) tool. At the moment, this tool is not available standalone and needs to be [built from source](../YarnSpinner-Programming/Building.md). + +## Localisation procedure + +1. We first use the tool to place unique **taglines** on each line of text that the end user will see. To do this, we execute the tool with the **taglines** command, eg: `YarnSpinnerConsole.exe taglines MyYarnFile.yarn.txt`. + +2. Next, we use the tool to generate a file of strings (**genstrings**) in '[comma separated value](https://en.wikipedia.org/wiki/Comma-separated_values)' (csv) format. `YarnSpinnerConsole.exe genstrings MyYarnFile.yarn.txt` will generate a file, (in this example MyYarnFIle.yarn_lines.csv), that can then distributed to translators. It is recommended that this file first be renamed using a language identifier before distribution, eg + ``` + MyYarnFIle.yarn_lines.enAU.csv + MyYarnFIle.yarn_lines.ptTL.csv + ``` +3. When the file is returned from translators, we then use Yarn Spinner's DialogueRunner inside Unity to set String Groups for the required language. + +## Footnotes +* While not essential that all files follow a standard, but highly recommended that consistency of format be used across all localisation files within a project eg [ISO-15897](https://www.iso.org/obp/ui/#iso:std:iso-iec:15897:ed-2:v1:en) +* Originally, Yarn Spinner used .json format. The Yarn Spinner Console can convert this json format to the new improved text format: `YarnSpinnerConsole.exe convert --yarn Ship.json` +* Command reference is available for YarnSpinnerConsole.exe by either running it with no arguments or by utilising the help command (`YarnSpinnerConsole.exe help`). Help for each command is available by using 'help command' (eg `YarnSpinnderConsole.exe help compile`) + + diff --git a/Documentation/YarnSpinner-Dialogue/README.md b/Documentation/YarnSpinner-Dialogue/README.md index a3eace024..c10462433 100644 --- a/Documentation/YarnSpinner-Dialogue/README.md +++ b/Documentation/YarnSpinner-Dialogue/README.md @@ -1,4 +1,4 @@ -# Yarn Dialogue - README +# Writing Yarn Dialogue - README ## Introducing Yarn Dialogue diff --git a/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Complex-Example.md b/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Complex-Example.md new file mode 100644 index 000000000..305bc84f2 --- /dev/null +++ b/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Complex-Example.md @@ -0,0 +1,133 @@ +# Yarn for Writers + +This document talks about how to use Yarn if you're using it to write content. It doesn't talk about how to integrate Yarn Spinner into your project; for that, see ["Using Yarn Spinner in your Unity game"](../YarnSpinner-Unity). + +## Lines + +Yarn lets you define multiple chunks of dialogue that are linked together. Each chunk is called a *node*. + +Nodes are filled with different kinds of text. The simplest is lines of dialogue, which look like this: + + Alice: Hey, I'm a character speaking in a dialogue! + Bob: Wild! + +Each line is delivered to your game one at a time. + +## Options + +To link a node to another node, you provide *options*. Options look like this: + + [[Go to the woods|GoToWoods]] + [[Go back to the city|GoToCity]] + +Options have two parts: the label, which is shown to the user, and the name of the node that we should link to when the user selects the option. The label and the node name are separated by a vertical bar (`|`). + +You don't have to provide the label. Instead, you can just provide the node name, like so: + + [[GoToCity]] + +If an option has no label, Yarn will automatically jump to that node when that line is run, and it won't show options to the player. + +When all of the lines in a node have been displayed, the dialogue system gives your game the list of available options. You then let the user choose an option, and then continue loading lines of dialogue, one at a time. + +If there are no options when we reach the end of a node, then we've reached the end of a conversation, and Yarn Spinner will let your game know. + +## Shortcut Options + +Sometimes, you'll want to add little branches to your conversation, but you don't want to create separate nodes for them. Instead, you can use *shortcut options*: + + Mae: What did you say to her? + -> Nothing. + Mae: Oh, man. Maybe you should have. + -> That she was an idiot. + Mae: Hah! I bet that pissed her off. + Mae: Anyway, I'd better get going. + +When this is run, Yarn Spinner will behave just as if you'd broken all of this up into multiple nodes. + +You can also attach conditions to shortcut options, which will make them only appear if a certain condition passes: + + Bob: What would you like? + -> A burger. <= 5>> + Bob: Nice. Enjoy! + -> A soda. <= 2>> + Bob: Yum! + -> Nothing. + Bob: Thanks for coming! + +Note that in the last example, there wasn't any attached text. If the player selected the last option ("Nothing."), then the next line to appear would be "Bob: Thanks for coming!" + +You can also nest these shortcut options, if you like. Be careful, though - too much nested options can make your text difficult to read. + +## Commands + +In addition to showing lines of dialogue, your game will probably want to run actions - things like "move the camera to position X", or "make character start smiling". You can use commands for this. + +Commands look like this: + + <> + +Any text inside the double-chevrons will be sent directly to your game as a string. It's up to you to decide what to do with that string. + +Yarn has a special command, called `stop`. If you include `<>` in your node, Yarn will stop the entire conversation when it reaches it. + +## Variables and If statements + +You can store numbers in variables. To do this, use the `set` command: + + <> + +You can check the value of a variable using the `if` command: + + <> + The door is unlocked! (This will only appear if $door_unlocked is equal to 1.) + <> + +## Expressions + +You can do math in an `if` command. For example: + + < 5>> + You have more than 5 stars! + <> + +You can also get fancier, and do stuff like this: + + < 0>> + You win the game! + < 0>> + You need to rescue more hostages! + <> + You failed to rescue the hostages before time ran out! + <> + +## Types + +There are four different types of value in Yarn: strings, numbers, booleans, and `null`. + +* Strings contain text. +* Numbers are floating-point numbers. +* Booleans are either true or false. +* `null` means no value. + +Yarn will automatically convert between types for you. For example: + + <> + The two strings are the same! + <> + + <> + Strings get joined together with other values! + <> + +**Warning:** Currently, variables can only store numbers. If you try to store anything else in a variable, it will get converted to a number first. + +## Functions + +You can call functions in your `if` commands. For example, Yarn Spinner provides a function called `visited`, which you can use to find out if a node has been entered before or not. It takes a single parameter (which is a string), and returns true or false depending on whether or not the node you specified has been entered. + + <> + We have gone to the city before! + <> + +You can't define your own functions inside Yarn itself, but they can be added at run-time. See ["Extending Yarn Spinner"](Extending.md) for more info. diff --git a/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Simple-Example.md b/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Simple-Example.md new file mode 100644 index 000000000..d4f158db6 --- /dev/null +++ b/Documentation/YarnSpinner-Dialogue/Yarn-HowTo-Write-Dialogue-Simple-Example.md @@ -0,0 +1,208 @@ +# Writing Yarn Dialogue - Simple Example + +### Style Guide + +`Inline Code` contain short snippets of code for your project + + Code Blocks contain segments or chunks of code for your project + +**Bold indicate actions (Select menu item, copying file, etc.)** + +***Bold italic text indicates emphasis*** + +> Blockquotes contain essential information + +## Tutorial + +> ***Note:*** This tutorial assumes that you know nothing about writing code, in particular how to use [Unity](http://www.unity3d.com) or the Yarn Editor. +> You do not need to know how to use those tools to write Yarn Dialogue. It is required that you know how to create a text file (.txt), which is different to a .doc, .docx, .rtf etc. document, in whatever text editor you are most comfortable using. Please refer to your friendly local computer expert if you are unsure how to do this. +> As you learn more about Yarn Dialogue, you may find the Yarn Editor useful as you progress with your authoring. It is a text editor that is designed to make Yarn Dialogue easier to create. + +## Introducing Yarn Dialogue + +Yarn Dialogue is designed for Authors who have little or no programming knowledge. It makes no assumptions about how your game presents dialogue to the player, or about how the player chooses their responses. These tasks are left to the game production team, using programming and design tools such as Unity3D and C#. + +### Simple Example Script + +We will create the essential Yarn Dialogue for the [Simple Example Dialogue](../Unity/Assets/Yarn%20Spinner/Examples/Demo%20Assets/Simple%20Example%20Script.yarn.txt). We will start off with the text as presented by the ingame characters, add in choices which are essentially what the player says to the characters, and have the characters react to the choices. + +Each section of text in Yarn Dialogue is known as a ***node***. + +A ***node*** consists of ***header data*** and ***body data***. The header data provides information about the body data, and the body data contains dialogue and options relating to the dialogue. + +In this example, our first node commences with two characters, A and B. + +We need to give this node a title, and in this example we will call it ***start***. There is no default title, it can be anything you like. +``` +title: start +``` + +> Node titles are case insensitive. The titles ***start***, ***Start***, ***START*** and ***StArT*** are different. + +> There is no default title. You will need to ensure that your game programmers know which node your game starts on, as it may not necessarily be the first node in your Yarn Dialogue file. + +The title tag is part of a collection of data known as ***header data*** that can refer to position, colour and other information about the dialogue. While the title tag is required, these other header data tags are optional and generally used later in game development when the dialogue is attached to scenes and graphical characters. + +To seperate the ***header data*** from the ***body data*** in the node, we then add in three `-` characters, known as a header delimiter. +``` +--- +``` +We can now add the starting text for our characters A and B. Their dialogue is so: +``` +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! + +``` +To indicate the end of the node, we add three `=` characters. This is called a ***node delimiter*** +``` +=== +``` + +Your ***node*** should now look like this +``` +title: start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +=== +``` + +Congratulations, you've just written your very first piece of Yarn Dialogue! + +### Adding Options and Replies + +#### Options +The next step we'll take is to add in some options to present to the player. We wish to present the player with the choice of two options. To do this, we use the `->` marker as the first characters in our line of text to tell the system the text is an option. + +We add this after the A and B character dialogue, but before the ending tag. +``` +-> What's going on +-> Um ok +``` + +Our Yarn Dialogue now reads as like this: +``` +title: start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +-> What's going on +-> Um ok +=== +``` + +#### Replies +Options aren't really that useful without a ***reply***. Replies are indented with four spaces. +``` + A: Why this is a demo of the script system! + B: And you're in it! +``` +The reply is placed immediately after the option to which it is connected. We'll add the above replies to the first option, resulting in our Yarn Dialogue now looking like this: +``` +title: start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +-> What's going on + A: Why this is a demo of the script system! + B: And you're in it! +-> Um ok +=== +``` +> Note: The order of the reply is important. In the above example, Character A replies, then Character B. We could easily reverse these lines if we wanted Character B to reply first. + +Finishing up here, we'll end the Dialogue with a pleasantary. + +``` +A: How delightful! +``` +We now have: +``` +title: start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +-> What's going on + A: Why this is a demo of the script system! + B: And you're in it! +-> Um ok +A: How delightful! +=== +``` + +### Branching to New Nodes +Additional nodes can be added to extend the story. These further nodes can introduce new characters, actions or provide different options and replies. + +We will now present the player with options of selecting what to do next. +``` +B: What would you prefer to do next? +[[Leave|Leave]] +[[Learn more|LearnMore]] +``` +The square double braces, `[[` and `]]`, indicate a branch to a different node. The vertical bar, ``|``, separates the string to be presented to the player (the option), from the destination ***node name***. Presentation of the new node will commence once the player has selected their chosen option text. Thus, the above code will present the player with two choices, 'Leave' and 'Learn More'. These options will take the player to the 'Leave' and 'LearnMore' nodes respectively. + +> Note: ***Node names*** must be a single string, that is to say they cannot have spaces in them. + +Our Dialogue now reads like this: +``` +title: Start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +-> What's going on + A: Why this is a demo of the script system! + B: And you're in it! +-> Um ok +A: How delightful! +B: What would you prefer to do next? +[[Leave|Leave]] +[[Learn more|LearnMore]] +=== +``` + +All we need to do now is add in two more nodes, the Leave and LearnMore nodes. We'll add a little bit of conversation in to Characters A and B just to differentiate between the two nodes. + +``` +title: Leave +--- +A: Oh, goodbye! +B: You'll be back soon! +=== +title: LearnMore +--- +A: HAHAHA +=== +``` + +Our final Yarn Dialogue file will read such: +``` +title: Start +--- +A: Hey, I'm a character in a script! +B: And I am too! You are talking to me! +-> What's going on + A: Why this is a demo of the script system! + B: And you're in it! +-> Um ok +A: How delightful! +B: What would you prefer to do next? +[[Leave|Leave]] +[[Learn more|LearnMore]] +=== +title: Leave +--- +A: Oh, goodbye! +B: You'll be back soon! +=== +title: LearnMore +--- +A: HAHAHA +=== +``` + +## Live example + +We have a fully parsed version of the above Yarn Dialogue available in our Unity examples directory as [Simple Example Script](../Unity/Assets/Yarn%20Spinner/Examples/Demo%20Assets/Simple%20Example%20Script.yarn.txt). Please note this differs from the above Yarn Dialogue in a couple of minor, yet important points: +* Extra header tags for colour and position of the dialogue +* Translation tags to aide with localization +These differences are generally created by programmers. It is envisaged that in the future they will be automatically generated by a Yarn Dialogue editor. diff --git a/README.md b/README.md index ae2deedeb..184735bf3 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ **[Yarn](https://github.com/infiniteammoinc/Yarn)** is a language that's designed to make it *super easy* to create interactive dialogue for games. Yarn's very similar in style to [Twine](http://twinery.org), so if you already know that, you'll be right at home! If you don't, that's cool - Yarn's syntax is extremely minimal, and there's not much there to learn. The Yarn language is used in a number of cool games, including [Night In The Woods](http://nightinthewoods.com) and [Knights and Bikes](https://www.kickstarter.com/projects/foamsword/knights-and-bikes). +> **New!** Join our [narrative game development](http://lab.to/narrativegamedev) Slack! +> **New!** Continual integration [API documentation](https://thesecretlab.github.io/YarnSpinner/html/) now available + **Yarn Spinner** interprets the Yarn language, and is written in [C#](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29). Yarn Spinner is designed to be easy to add to [Unity](http://www.unity3d.com) games, but it's also intended for use in other contexts as well. > ***Important:*** Yarn Spinner is still under development, and we haven't made our 1.0 release yet. It's *probably* fine to use right now, but there are a few bits and pieces that might change between now and first release. @@ -18,7 +21,6 @@ ## Quick Start - Documentation * If you're already familiar with Unity, we recommend you head straight to our [Yarn Spinner With Unity Quickstart](Documentation/YarnSpinner-with-Unity-QuickStart.md) document. - ## What To Do Next * Learn how to [build Yarn Spinner from source.](Documentation/Building.md) @@ -31,13 +33,13 @@ ## License Yarn Spinner is available under the [MIT License](LICENSE.md). This means that you can use it in any commercial or noncommercial project. The only requirement is that you need to include attribution in your game's docs. A credit would be very, very nice, too, but isn't required. If you'd like to know more about what this license lets you do tldrlegal.com have a [very nice write up about the MIT license](https://tldrlegal.com/license/mit-license) that you might find useful. - ## Made by Secret Lab! Yarn Spinner was originally created by [Secret Lab](http://secretlab.com.au), an Australian game dev studio. [Come say hi](https://twitter.com/thesecretlab)! You can visit the [Yarn Spinner page](http://www.secretlab.com.au/yarnspinner) on the Secret Lab website for a little more info, and to donate to Yarn Spinner open source development at Secret Lab. The awesome [logo](Documentation/YarnSpinnerLogo.png) was made by the excellent [Rex Smeal](https://twitter.com/RexSmeal), and is under the [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + ## Help Us Make Yarn Spinner! Yarn Spinner needs your help to be as awesome as it can be! You don't have to be a coder to help out - we'd love to have your help in improving our [documentation](Documentation/README.md), in spreading the word, and in finding bugs. diff --git a/Tests/TestCases/SaveTest.json b/Tests/TestCases/SaveTest.json new file mode 100644 index 000000000..d7e2fc3ba --- /dev/null +++ b/Tests/TestCases/SaveTest.json @@ -0,0 +1,12 @@ +[ + { + "title": "Start", + "tags": "", + "body": "This is the first line.\r\nThis is the second line.\r\nThis is the third line.\r\nThis is the fourth line.\r\n", + "position": { + "x": 543, + "y": 269 + }, + "colorID": 0 + } +] \ No newline at end of file diff --git a/YarnSpinner/YarnSpinner.csproj b/YarnSpinner/YarnSpinner.csproj index 671197342..262fc3007 100644 --- a/YarnSpinner/YarnSpinner.csproj +++ b/YarnSpinner/YarnSpinner.csproj @@ -1,4 +1,4 @@ - + Debug @@ -49,6 +49,10 @@ + + ..\packages\Newtonsoft.Json.9.0.1\lib\net35\Newtonsoft.Json.dll + True + ..\packages\Newtonsoft.Json.9.0.1\lib\net35\Newtonsoft.Json.dll @@ -85,5 +89,8 @@ + + + \ No newline at end of file diff --git a/YarnSpinner/packages.config b/YarnSpinner/packages.config index 5986718ac..e245bc76b 100644 --- a/YarnSpinner/packages.config +++ b/YarnSpinner/packages.config @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/run-tests.sh b/run-tests.sh index af44dac91..8301f08ac 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -2,7 +2,7 @@ # The MIT License (MIT) # -# Copyright (c) 2015 Secret Lab Pty. Ltd. and Yarn Spinner contributors. +# Copyright (c) 2015-2017 Secret Lab Pty. Ltd. and Yarn Spinner contributors. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal