Git Product home page Git Product logo

ink's People

Contributors

13xforever avatar atlas48 avatar behindcurtain3 avatar bitbutter avatar bncastle avatar cduquesne avatar chromy avatar elliotherriman avatar ephread avatar iainmerrick avatar joethephish avatar joningold avatar kumokairo avatar landryyrdnal avatar lazerwalker avatar lptech1024 avatar mattconrad avatar mwchase avatar myonmu avatar ncthbrt avatar premek avatar pvanliefland avatar russellquinn avatar sequitur avatar sputtering avatar stackh34p avatar stratege avatar ststep avatar tomkail avatar y-lohse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ink's Issues

Unexpected behavior for Knot parameter.

I encounter a problem which I believe is caused by the use of a reserved word, hidden variable, or token value as knot parameter.

Both knots in the following snippet are functionally identical. Despite this, one prints out the correct value of 0, and the other, an incorrect value of 1. The only difference appears to be the name of the parameter.

Would it be possible to have the compiler catch this, whatever the root cause is?

== Begin ==
Fun with params
+ Toggle Lamp (working) -> ToggleLamp(false)
+ Toggle Lamp (broken) -> ToggleLamp2(false)
* I'm Done -> DONE

== ToggleLamp(isOn) ==
the lamp is on? {isOn}
-> Begin

== ToggleLamp2(on)
the lamp is on? {on}
-> Begin

Exception on runtime on MacOS

Hello,

I got this exception running my build game on MacOs when a ink script is executed.

TypeLoadException: Could not load type 'Newtonsoft.Json.Linq.JArray' from assembly 'Newtonsoft.Json'
The strange thing is that all run well on the Unity3d editor. Checking the build I say that all dlls were in place and the ink scripts were ok...

captura de tela 2016-03-16 15 52 59

JIT compiler invoked when deserializing story on iOS

This is for version 0.2.3 alpha.

I had not tested on device for some time, so not quite sure when this started happening. I fully realize that this is more an issue with the NewtonSoft.JSON dll than it is with the Inkle library, but seeing as how you publish on iOS as well I thought it worth a mention :-)

I can provide the JSON string for the story, or a more complete example if you want, but I think this will be easily reproducible.

running tests...InkTests

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)

FAILED: LoadTestFile

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)

reason: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeInitializationException: An exception was thrown by the type initializer for Newtonsoft.Json.Utilities.ConvertUtils ---> System.TypeInitializationException: An exception was thrown by the type initializer for System.Collections.Generic.EqualityComparer`1 ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ExecutionEngineException: Attempting to JIT compile method 'System.Collections.Generic.GenericEqualityComparer`1<Newtonsoft.Json.Utilities.ConvertUtils/TypeConvertKey>:.ctor ()' while running with --aot-only.

  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <filename un    known>:0 
  at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.EqualityComparer`1[Newtonsoft.Json.Utilities.ConvertUtils+TypeConvertKey]..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Collections.Generic.Dictionary`2[Newtonsoft.Json.Utilities.ConvertUtils+TypeConvertKey,Newtonsoft.Json.Serialization.Func`2[System.Object,System.Object]].Init (Int32 capacity, IEqualityComparer`1 hcp) [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.Dictionary`2[Newtonsoft.Json.Utilities.ConvertUtils+TypeConvertKey,Newtonsoft.Json.Serialization.Func`2[System.Object,System.Object]]..ctor () [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Utilities.ThreadSafeStore`2[Newtonsoft.Json.Utilities.ConvertUtils+TypeConvertKey,Newtonsoft.Json.Serialization.Func`2[System.Object,System.Object]]..ctor (Newtonsoft.Json.Serialization.Func`2 creator) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Utilities.ConvertUtils..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Newtonsoft.Json.Linq.JToken.ToObject (System.Type objectType) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Linq.JToken.ToObject[Int32] () [0x00000] in <filename unknown>:0 
  at Ink.Runtime.Story..ctor (System.String jsonString) [0x00000] in <filename unknown>:0 
  at LiveSequenceManager.LoadStory (System.String storyName) [0x00016] in /Users/jonathanculp/Documents/Guildlings/Assets/Scripts/Ink/LiveSequenceManager.cs:104 
  at InkTests.LoadTestFile () [0x00000] in /Users/jonathanculp/Documents/Guildlings/Assets/Scripts/Testing/Tests/Ink/InkTests.cs:62 
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at UnitTestHarness.RunTest (System.Reflection.MethodInfo info) [0x0000f] in /Users/jonathanculp/Documents/Guildlings/Assets/Scripts/Testing/Framework/UnitTestHarness.cs:38 

Some of that trace - specific to my project obviously, but I believe I've properly isolated the cause to just the provided Inkle libraries. I'm definitely not ruling out the possibility that the problem is on my end.

I don't have the best understanding of when or how the JIT compiler is invoked. But I do remember this having worked on previous versions. I'll start reviewing the changes.

Out of curiosity whats the source of your Newtonsoft.Json.dll? I remember that the mono version of this assembly had many compatibility issues with iOS. Many unity users will be using a ported version of this assembly from the asset store that was written specifically to be more compatible with iOS's AOT restrictions. It forked quite a long time ago, so it's more than a few versions behind the official Newtonsoft project. Despite that, for many of us, its a better choice.

-Jonathan

Empty lines between paragraphs

I did not see this mentioned in the tutorial anywhere so I don't know if this feature exists, but it would be nice to be able to have a blank line between paragraphs or between prompt and selections. For instance, I'm trying to make a quit game prompt:

=== quit_prompt(-> return_to) ===
Done so soon?

  • [Yes, I'm outta here!] -> quit_game
  • [No, let's keep going] -> return_to

But I would want it to display a space between the prompt and the choice, as a stylistic decision, and there are many cases where you are writing longer paragraphs where whitespace would be helpful.

Unhandled exception in Mac Unity 5.3.1f1 with 0.1.2 ink-engine.dll

I can get 0.1.2 inklecate to successfully run an .ink file in the Mac OS Terminal window, but when I try to integrate a created json file and dll into Unity 5.3.1f1 following the RunningYourInk doc guide, Unity throws an error at the "Story _inkStory;" line of the example wrapper script the doc suggests. Unity is complaining that 'Newtonsoft.Json' is not present. I am using the provided mac inklecate and ink-engine.dll files from https://github.com/inkle/ink/releases, I did not compile on my own.

Error:

Unhandled Exception: Mono.CSharp.InternalErrorException: Assets/Ink/Script.cs(7,14): Script ---> Mono.CSharp.InternalErrorException: Assets/Ink/Script.cs(13,15): Script._inkStory ---> System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies.
File name: 'Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
at (wrapper managed-to-native) System.MonoCustomAttrs:GetCustomAttributesInternal (System.Reflection.ICustomAttributeProvider,System.Type,bool)
at System.MonoCustomAttrs.GetCustomAttributesBase (ICustomAttributeProvider obj, System.Type attributeType) [0x00000] in :0
at System.MonoCustomAttrs.GetCustomAttributes (ICustomAttributeProvider obj, System.Type attributeType, Boolean inherit) [0x00000] in :0
at System.MonoType.GetCustomAttributes (System.Type attributeType, Boolean inherit) [0x00000] in :0
at Mono.CSharp.AttributeTester.GetObsoleteAttribute (System.Type type) [0x00000] in :0
at Mono.CSharp.Expression.ResolveAsTypeTerminal (IMemberContext ec, Boolean silent) [0x00000] in :0
at Mono.CSharp.MemberBase.ResolveMemberType () [0x00000] in :0
at Mono.CSharp.MemberBase.Define () [0x00000] in :0
at Mono.CSharp.Field.Define () [0x00000] in :0
at Mono.CSharp.TypeContainer+MemberCoreArrayList.DefineContainerMembers () [0x00000] in :0
--- End of inner exception stack trace ---
at Mono.CSharp.TypeContainer+MemberCoreArrayList.DefineContainerMembers () [0x00000] in :0
at Mono.CSharp.TypeContainer.DefineContainerMembers (Mono.CSharp.MemberCoreArrayList mcal) [0x00000] in :0
at Mono.CSharp.Class.DefineContainerMembers (Mono.CSharp.MemberCoreArrayList list) [0x00000] in :0
at Mono.CSharp.TypeContainer.DoDefineMembers () [0x00000] in :0
at Mono.CSharp.Class.DoDefineMembers () [0x00000] in :0
at Mono.CSharp.TypeContainer.Define () [0x00000] in :0
at Mono.CSharp.ClassOrStruct.Define () [0x00000] in :0
at Mono.CSharp.Class.Define () [0x00000] in :0
at Mono.CSharp.RootContext.PopulateTypes () [0x00000] in :0
--- End of inner exception stack trace ---
at Mono.CSharp.RootContext.PopulateTypes () [0x00000] in :0
at Mono.CSharp.Driver.Compile () [0x00000] in :0
at Mono.CSharp.Driver.Main (System.String[] args) [0x00000] in :0

The following assembly referenced from /Users/joshualawrence/Dropbox/Unity/Hypertext2/Assets/Ink/ink-engine.dll could not be loaded:
Assembly: Newtonsoft.Json (assemblyref_index=2)
Version: 7.0.0.0
Public Key: 30ad4fe6b2a6aeed
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/joshualawrence/Dropbox/Unity/Hypertext2/Assets/Ink/).

Could not load file or assembly 'Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies.
Missing method .ctor in assembly /Users/joshualawrence/Dropbox/Unity/Hypertext2/Assets/Ink/ink-engine.dll, type Newtonsoft.Json.JsonObjectAttribute
Can't find custom attr constructor image: /Users/joshualawrence/Dropbox/Unity/Hypertext2/Assets/Ink/ink-engine.dll mtoken: 0x0a00002d

Script:

using UnityEngine;
using System.Collections;
using Ink.Runtime;

public class Script : MonoBehaviour {

    // Set this file to your compiled json asset
    public TextAsset inkAsset;

    // The ink story that we're wrapping
    Story _inkStory;

    void Awake()
    {
        _inkStory = Story.CreateWithJson(inkAsset.text);
    }

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

        while (story.canContinue) {
            Console.WriteLine (story.Continue ());
        }

        if( story.currentChoices.Count > 0 ) 
        {
            for (int i = 0; i < story.currentChoices.Count; ++i) {
                ChoiceInstance choice = story.currentChoices [i];
                Console.WriteLine ("CHOICE {0}: {1}", (i + 1), choice.choiceText);
            }
            story.ChooseChoiceIndex (index);
        }

    }
}

Source/Packages

I noticed you have the NewtonSoft dll in a source folder and you have the NUnit package uploaded. These should be listed in your packages.config and any developer who forks or clones the repo will "restore" those locally. No need to track them in source.

Save/Load Methods

Hello,
Maybe I didn't find it in tutorials, but what is the best way to make saving/loading in game?
Am I right, we can't do anything about internal variables, that count how many times player diverted to some knot, stitch, or chose option with label on it? It seems that we can't get any value from them in C# and we can't give these values to global variables. And it seems that there is no reset for them besides restarting the story too.
Am I missing something big here, something like states we can address to and get all variables on that moment correctly? Or should I create my own system with global variables that will duplicate the work of knots, stitches, labels for everything I want (it is still a good question how to work with conditions that depend on "entrance count", not on variables), and with every load I should restart the story? Or work only with variables if I want to successfully save and load it?
I don't believe that saving is a complicated thing, when everything in Ink is so convenient. I hope you can give a hint :)

More qsts about conditional syntax

This example :

{ 
    - x == 0:
        ~ y = 0
    - x > 0:
        ~ y = x - 1:
    - else:
        ~ y = x + 1;
}

Seems to have a superfluous ':' in the second switch (it outputs that character in inklecate). This is also the case with the if-then example above it. However, the ';' is not outputted.

Some older Ink version syntax left-overs? You have other examples that include neither the end-of-line colon nor the semi-colon, and the parser handles those fine, so it doesn't seem as if either character serves any purpose any longer.

Documentation for encoding of string values seems wrong

In file Documentation/ink_JSON_runtime_format.md it is stated that a string value must be prepended with ^ but in the examples string values are prepended with $

Given that the runtime looks for ^ at the beginning of string objects I guess that the examples using $ are wrong?

Regards,

Martin

Inklecate Crash When Compiling Ink Script with Conditional Statement

Using version 0.33 of ink, I ran into a problem with an ink script trying to use ink's ternary style operator on a variable to alter some text in-line.

I was hoping to use the following example from the WritingWithInk.md page to do this:

  • "His real name was {met_blofeld.learned_his_name: Franz|a secret}."

But when changing 'met_blofeld.learned_his_name' to a different conditional statement, the compile failed and crashed out. I've attached an ink script that (at least for me) demonstrates the crash, and a change I can make that makes the compile successful. Neither one runs as I would expect (i get no output from this script at all and it seems like I should be getting something? Not even the question at the beginning?) I'm assuming that part is just something silly I've done wrong.

I don't yet think I understand the parser/compiler code enough to try to take this on myself, but figured I would just post up here since I found a repeatable issue.

error.txt

sequence choices

Doesn't seem possible? E.g.:

Welcome to my Lair:

  • {~ Thanks! | Great! | Love it here.. } -> good_reaction
  • {~ Yikes! | Oh no! | [flee] } -> bad_reaction

OS X crash with Play mode

While building a text-only adventure game, I've been using Play mode for testing. My combat subsystem, a tunnel named fight crashes when it's invoked, for some reason. Here's the stack trace:

Unhandled Exception:
System.Exception: Shouldn't ever have a null value where it couldn't be found at all
  at Ink.Runtime.VariablesState.GetRawVariableWithName (System.String name, Int32 contextIndex) <0x13c6a40 + 0x000af> in <filename unknown>:0
  at Ink.Runtime.VariablesState.GetVariableWithName (System.String name, Int32 contextIndex) <0x13c69a8 + 0x00023> in <filename unknown>:0
  at Ink.Runtime.VariablesState.GetVariableWithName (System.String name) <0x13c6978 + 0x0001f> in <filename unknown>:0
  at Ink.Runtime.Story.PerformLogicAndFlowControl (Ink.Runtime.Object contentObj) <0x13bb608 + 0x0120b> in <filename unknown>:0
  at Ink.Runtime.Story.Step () <0x13baa20 + 0x00167> in <filename unknown>:0
  at Ink.Runtime.Story.ContinueInternal () <0x13ba250 + 0x00083> in <filename unknown>:0
  at Ink.Runtime.Story.Continue () <0x13c6398 + 0x00027> in <filename unknown>:0
  at Ink.CommandLinePlayer.EvaluateStory () <0x13c6238 + 0x0003f> in <filename unknown>:0
  at Ink.CommandLinePlayer.Begin () <0x13c5c08 + 0x00567> in <filename unknown>:0
  at Ink.CommandLineTool..ctor (System.String[] args) <0x128b1c0 + 0x0080f> in <filename unknown>:0
  at Ink.CommandLineTool.Main (System.String[] args) <0x128af30 + 0x00023> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: Shouldn't ever have a null value where it couldn't be found at all
  at Ink.Runtime.VariablesState.GetRawVariableWithName (System.String name, Int32 contextIndex) <0x13c6a40 + 0x000af> in <filename unknown>:0
  at Ink.Runtime.VariablesState.GetVariableWithName (System.String name, Int32 contextIndex) <0x13c69a8 + 0x00023> in <filename unknown>:0
  at Ink.Runtime.VariablesState.GetVariableWithName (System.String name) <0x13c6978 + 0x0001f> in <filename unknown>:0
  at Ink.Runtime.Story.PerformLogicAndFlowControl (Ink.Runtime.Object contentObj) <0x13bb608 + 0x0120b> in <filename unknown>:0
  at Ink.Runtime.Story.Step () <0x13baa20 + 0x00167> in <filename unknown>:0
  at Ink.Runtime.Story.ContinueInternal () <0x13ba250 + 0x00083> in <filename unknown>:0
  at Ink.Runtime.Story.Continue () <0x13c6398 + 0x00027> in <filename unknown>:0
  at Ink.CommandLinePlayer.EvaluateStory () <0x13c6238 + 0x0003f> in <filename unknown>:0
  at Ink.CommandLinePlayer.Begin () <0x13c5c08 + 0x00567> in <filename unknown>:0
  at Ink.CommandLineTool..ctor (System.String[] args) <0x128b1c0 + 0x0080f> in <filename unknown>:0
  at Ink.CommandLineTool.Main (System.String[] args) <0x128af30 + 0x00023> in <filename unknown>:0

Glue and Paragraphs

Back again.

Before I get down to the nuts and bolts here, let me just reiterate that I really love what you guys have done here. I've looked at a lot of IF scripting languages over the past few years while working on my own games scripting language v1 and v2, and Ink is - IMO - the best combination of power and simplicity I've encountered so far. Ink is awesome, and you guys are awesome for sharing it with the rest of us.

That said, nothing is perfect. Most of the nits I have a pretty minor things, but I am really not keen on your "single new line -> paragraph break" convention. I commented on this earlier in the chat, but I'd like to bring this up again now that I've worked some on a bare-bones implementation in Java and have a bit more perspective, because I do feel that this is a weakness in Ink, and perhaps something you should (re)consider.

My initial disquiet with this mechanism was due to my experiences collaborating across various technical platforms. Since I work mostly in Linux and the people I collaborate with in Windows or Max, I'd often have someone writing in one editor, and me then having to edit the text in another. That did cause issues from time to time - esp. if you're working with editors that do hard-wrapping (such as many IDE's). But while annoying, this is not a big deal (just requires some editing discipline).

I think this convention has two other effects, though, which IMO are much more serious:

  • It forces Ink to include an unnecessary scripting element: Glue
  • It makes the Ink implementation a lot more complicated/fragile than it needs to be

My suggestion would be to go with "hard-wrapping" by default, similar to Markdown syntax and Mediawiki syntax. Basically:

  • A single newline does not cause a paragraph break (unless the next line is syntax; e.g., stitch, expression, choice, etc)
  • A double newline causes a paragraph break.
  • If you want to support something like the request in #8, three or more newlines in the syntax could be used to create extra line breaks (this is standard markdown syntax). I kind of agree with Jon that it shouldn't really be needed, though.

Glue

Feel free to correct me if I'm off, but as far as I can see, the necessity for "Glue" (<>) is entirely the consequence of following the "single new line -> paragraph break" convention.

Without that convention, the core glue example:

=== hurry_home ===
We hurried home <> 
-> to_savile_row 

=== to_savile_row ===
to Savile Row 
-> as_fast_as_we_could

=== as_fast_as_we_could ===
<> as fast as we could.

Would just be:

=== hurry_home ===
We hurried home 
-> to_savile_row 

=== to_savile_row ===
to Savile Row 
-> as_fast_as_we_could

=== as_fast_as_we_could ===
as fast as we could.

Your glue test case:

"Some <> 
content<>
with glue."

Would just be:

"Some 
content
with glue."

A more complex example:

- I looked at Monsieur Fogg 
*   ... and I could contain myself no longer.
    'What is the purpose of our journey, Monsieur?'
    'A wager,' he replied.
    * *     'A wager!'[] I returned.
            He nodded. 
            * * *   'But surely that is foolishness!'
            * * *  'A most serious matter then!'
            - - -   He nodded again.
            * * *   'But can we win?'
                    'That is what we will endeavour to find out,' he answered.
            * * *   'A modest wager, I trust?'
                    'Twenty thousand pounds,' he replied, quite flatly.
            * * *   I asked nothing further of him then[.], and after a final, polite cough, he offered nothing more to me. <>
    * *     'Ah[.'],' I replied, uncertain what I thought.
    - -     After that, <>
*   ... but I said nothing[] and <> 
- we passed the day in silence.
- -> END

Could be written as follows (note the use of diverts to "glue" together across break syntax, as well as line breaks to keep the code nicely formatted):

- I looked at Monsieur Fogg
*   ... and I could contain myself no longer.

    'What is the purpose of our journey, Monsieur?'

    'A wager,' he replied.
    * *     'A wager!'[] I returned.

            He nodded.
            * * *   'But surely that is foolishness!'
            * * *  'A most serious matter then!'
            - - -   He nodded again.
            * * *   'But can we win?'

                    'That is what we will endeavour to find out,' he answered.
            * * *   'A modest wager, I trust?'

                    'Twenty thousand pounds,' he replied, quite flatly.
            * * *  I asked nothing further of him then[.], and after a final, polite
                    cough, he offered nothing more to me. -> after_that
    * *     'Ah[.'],' I replied, uncertain what I thought.
    - -     (after_that) After that, -> we_passed
* ... but I said nothing[] and -> we_passed 
- (we_passed) we passed the day in silence.
- -> END

Note that in the above, I refer to "break syntax" as those syntax elements that break up the script: knots, stitches, choices, gathers, etc.

TL;DR - my impression at this point is that glue is only required because of the choice of "single new line -> paragraph break". At the moment, I can't really see any obvious or common use-cases that makes it worthwhile to litter the code with a lot of <> syntax, as opposed to simply using the double newline convention (+ the occasional divert - something that already works that way in the current Ink syntax).

Code Complexity

The thing that really cements my unease with the glue mechanic, is that it seems to make the Ink runtime/parser a lot more complex than it needs to be.

Based on my experience implementing a markdown style parser vs the work I've done on a Java Ink runtime so far, the former just seems a lot more straightforward.

In the markdown style, you simply parse text/lines until you hit break syntax or a double newline (which is a break syntax itself). Because paragraph breaks are explicit, you always parse/compute until you hit one. It's pretty simple with no exceptions.

I can't say the same for dealing with this in current Ink script. Every time you process a line, you need to check for glue either at the beginning or the end of the line, requiring alternative back-tracking or look-ahead. The Glue syntax is an exception to the "new line -> paragraph break' rule, and because Ink is as powerful as it is, this becomes a really important exception.

The result is a lot of complicated code to deal with this exception.

I was rather puzzled by Joseph's comments earlier about whitespace handling being a problem. No longer, after implementing glue, and having to compensate for all the potential white-space issues that this syntax adds to the code. I haven't checked the C# code in detail, but I found myself having to add a lot of extra whitespace checking because of glue.

I smiled a bit when I read your comment in the runtime that goes "This code is slightly fragile" when discussing lookahead due to glue. Indeed.

Bottom line

In short, I think that there are good reasons to go with the markdown syntax for paragraph breaks both from the POV of the writer and the POV of the developer.

I'm not interested in forking or creating a variant of Ink, and I do realize that you may have other priorities, so if you want to kill this discussion for now, I'll accept that.

I think you should consider the issue, though. I may be overlooking something, but I feel pretty sure that the markdown style paragraph formatting would result in simpler (and by extension - less brittle) library code and it definitely makes the syntax simpler. For a project that will - hopefully - pick up a lot of fans and live for many years to come, such things are better fixed early than late.

[Discussion] What kind of Unity templates would be useful?

I think I'm going to make a few basic UI templates for displaying ink stories. One of the things I'm trying to decide is whether to rely on the TextMeshPro plugin, which I believe is essential for anyone trying to make a Unity game with text (in-line styling and animation and everything you could possibly want to do with text is just so simple, not to mention actual accurate word-wrapping and resize to fit and rendering and and and). But it's also $65USD and I'd hate to leave out people who can't afford that. Maybe a separate example that shows specifically what can be accomplished with Ink and TMP working together? Thoughts?

Ideally the Ink stories could serve as practical examples for everything covered in the "Writing With Ink" documentation, but my primary focus is on demonstrating how to display Ink in Unity UI. Here are the examples/templates I'm planning:

  1. Barebones Inkle style of lines being added to previous content. Demonstrate formatting syntax/parsing for paragraph indentation and line breaks. How to dynamically display choices as buttons.
  2. Advanced Inkle style (Sorcery-esque combat? Something new?) that uses ink logic and variables to simulate something interesting. Game observes and sets ink variables. Demonstrate calling game functions from ink script, etc.
  3. Phoenix Wright/JRPG/Visual Novel style of one ink line displayed at a time. Character name and emotion (stage direction) parsing.
    283371-phoenix-wright-ace-attorney-nintendo-ds-screenshot-select
  4. Twine style embedded links (??). I got the proof of concept working with TextMeshPro, but I'm not sure how solid I can make this yet.
  5. Something obvious I missed?

Sequence on variable/value

Ink has some pretty powerful mechanisms, but I'm missing one construct that I found very useful for writing texts with variables in my own scripting language. An example:

He brought me [# number | nothing! The cad|one calling bird|two french hens|three turtle doves|an aviary#].

This simple returns the first element in the construct if number is <= 0 (or false), the last element in the construct if number >= maximum elements, and the appropriate value if number is a valid index in the sequence.

E.g.,, for number = 0, you get:
He brought me nothing! The cad.
For number = 2, you get:
He brought me two french hens.
For numbers >= 4 you get:
He brought me an aviary.

You have something a little similar in your inline if-then { val : text1 | text0 }, but that's of course not as powerful ([#ย #] started out as a similar construct, before I decided to flip the order and generalize it), and I haven't noticed anything that provides the same functionality.

Perhaps I missed something? How do you handle that kind of variable-dependent writing in-line today?

GetIncludePaths parsing illegal characters -- Path.Combine error

I have two Ink files:

Test.Ink:

test

and Global.Ink:

helloworld

I get this error when the plugin compiles:

error

I'd have a better analysis of the offending code but I don't have a working debugger at the moment. Here's the GetIncludePaths code which has some weirdness that I've highlighted:
getincludepaths

"index+"?

And then I really don't understand this. If I just comment out the include path parsing, everything works.

working

commented

Word wrap bug when writing ink files in sublime

When I write an ink file, text wraps on the line instead of on the word. This makes long blocks of text difficult to read/write.
I've attached an example showing that the issue is ink-specific. Is anyone else getting this behavior? Is there a simple setting I've missed that would allow me to restore word wrapping?

Thanks!

sublime_ink_wrap

sublime_textfile_wrap

Discussion forum

Hey guys!

I was investigating some possible options for hosted forums etc, and the more time I spent doing that, the more I realised that github issues itself really isn't far off from a discussion forum anyway.

So I propose the following: For discussions, let's just use the newly-created discussion label here. As far as when to close a discussion issue it's a bit ambiguous, but let's try to tidy up after ourselves.

On the one hand, issues is meant to be a bug tracker, but I think it could work well for discussions as well, as we've already been using it.

The other nice thing is that with the label you essentially have a forum permalink too.

jInk - Java Ink

As I've mentioned, I've been doodling around an Ink implementation in Java during the weekend. I've put the results up here in case anyone else is interested:
https://github.com/micabytes/jink

It essentially implements Part 1 of the Ink documentation, with a (fairly) comprehensive set of tests based on the examples in the docs. Tests are written using Spec2 (Scala), but should be easily readable (minimal Scala syntax involved).

I'm likely to be a bit busy during the coming month, so probably won't do very much more work on it between now and late April. My first impression of working with this has been positive though. I use a similar IF parser in my current (Android - hence the need for Java) game engine, and I am thinking there'd be some advantages to using Ink instead of my home-grown solution. So unless something happens to change my mind, I'll probably pick up work on this again later with a view to making it "ink-complete".

Anyway, it's available if anyone wants to play around with it. Haven't looked into a license yet, though I expect I'll MIT it to be compatible with this. If anyone wants to contribute/help, that would certainly be appreciated.

cycling links and interchangeable paragraphs

Hi guys:

I wonder if Ink is capable of doing cycling links like in twine without further work on the engine part. Or for example, has whole paragraphs disappearing and changing upon a click, like you, Inkle, did in First Draft of the Revolution.

If so, how?

Regards.

StoryException has accessability level Internal

Should be public. Can't currently catch an exception of type StoryException.

Use case: I'm writing a series of unit tests for an ink story. Would like to test that attempting to call an unbound external function throws a StoryException. Since StoryException is internal, I have to catch its parent class, Exception. But I do not want an unrelated exception to cause this test to pass when it shouldn't.

Sticky choices not sticky

I'm seeing a behavior with InkEngine.dll where a sticky choice disappears from the choices list after a call to Story.Continue. Choice is properly sticky in play mode with inklecate. Curious as to why play-mode and engine dll differ. Will update this issue with minimal example soon. On version 0.2.0 alpha.

I will test with 0.2.1 alpha and will also provide minimal example soon.

Backslash escaping not working (on Windows?)

A report from @Horatio-Blackwood, via HipChat.

VAR char_name = "Joe"

* \ {char_name}: This is the choice
The end.
-> DONE

(We use the backslash in this situation, somewhat awkwardly, to escape the following space and allow "Joe" to appear in the choice text, rather than turning {char_name} into a conditional for the choice.)

This appears to work:

  • On Mac
  • On Windows via CLI

But not:

  • On Windows, via Unity integration (for @Horatio-Blackwood). It prints the backslash itself.

Need to reproduce, and debug.

Issue with labels

Hello!
Studying the Ink now, testing examples that are in tutorial. And stumbled on some issue with labels, that exist in your own example, maybe it will be helpful:

  • (opts)
    • 'Can I get a uniform from somewhere?'[] you ask the cheerful guard.
      'Sure. In the locker.' He grins. 'Don't think it'll fit you, thought.'
    • 'Tell me about the security system.'
      'It's ancient,' the guard assures you. 'Old as coal.'
    • 'Are there dogs?'
      'Hundreds,' the guard answers, with a toothy grin. 'Hungry devils, too.'
      // We require the player to ask at least one question
    • {loop} [Enough talking]
      -> done
    • (loop)
      // loop a few times before the guard gets bored
      { -> opts | -> opts | }
      He scratches his head.
      'Well, can't stand around talking all day,' he declares.
    • (done)
      You thank the guard, and move away.

What happens here, entering the "loop" label doesn't increase count (how many times we entered this gather), so choice [Enough talking] never appear - Ink thinks that loop == 0. Problem disappears, if we add symbol before list of diverts. So I think issue is with immediate divert in gather - without at least one symbol Ink doesn't increase count for label.
It is not critical one, but if this is really an issue, maybe you can warn others about it till it'll be fixed.

By the way, very good project. Waited for it since the announcing and it totally worth the waiting, thanks for making it available.

Issue with Newtonsoft.Json in Unity build (solved)

I've met a problem after building the application in Unity, Log showed this type of error:

TypeLoadException: Could not load type 'Newtonsoft.Json.Linq.JArray' from assembly 'Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'.

If it's not so obvious and I just didn't know anything about it, maybe it's worth to add a solution for such cases in RunningWithInk documentation: In "Edit -> Project settings -> Player -> Other settings" you should set API compatibility level from .NET 2.0 subset (default one) to .NET 2.0.

[HELP] How to bind dummy external functions for the editor player window?

Hi. Forgive me if this is the wrong place to ask this question.

I'm getting a story exception when testing an Ink script in the player window because I have external functions defined. Is there a good way to assign them dummy bindings in the editor only? I see there is an allowExternalFunctionFallbacks flag but what does that do exactly?

I don't know how to get the Story object from the InkPlayerWindow script. Perhaps an event could be added that fires when the window loads a story?

documentation for json files?

I've been taking a look at ink this weekend (great work btw, and kudos for open sourcing), with an eye to pitching in towards a javascript runtime (i'm a web guy and would love to play ink games in the browser, it seems such a natural fit with the json output!).

My main stumbling point so far has been the json files themselves, they seems very complex and verbose, even when compiling the smallest hello world example.

I know you have said that there are changes on the way to simplifying the format, so i'm wary of diving too deep or making any suggestions, but I guess i'm wondering if you have either of:

  • A timescale on the refactor
  • Any documentation on the compiled format that people like me could use when tinkering with the language?

In case you are interested, the bit that confuses me the most is:

[
        {
          "cmd": "EvalStart"
        },
        {
          "cmd": "BeginString"
        },
        {
          "div": ".^.s",
          "push": "func"
        },
        {
          "cmd": "EndString"
        },
        {
          "cmd": "BeginString"
        },
        ".\"",
        {
          "cmd": "EndString"
        },
        {
          "cmd": "EvalEnd"
        }

]

Which seems to be repeated almost once for every line of text. I think I get what it's doing, but it seems like a hell of a lot of boilerplate for what I assume is basically printing a string? (i'm assuming some part of the more advanced features of the language require the verbosity?).

Anyway, thanks for reading, and sorry for the long non-issue (and the slight whiff of entitlement), i'd just REALLY love to get involved on the js side, but don't want to waste time if it's all going to change under me in the immediate future.

Parameter coersion fails for externally bound function of type Action<string,int>

Having some trouble with external function binding. I was able to get a function of type Action to work, but another one of type Action<string,int> is throwing exceptions when called. Specifically "failed to cast string to int32". There may be function signatures that will trigger this but I have not explored any other combinations.

Minimal example provided below

Cheers,
-Jonathan

Ink File:

EXTERNAL grow_apples(amount)
EXTERNAL give_apples_to(id, amount)

-> Begin

== Begin ==
{grow_apples(4)}
{give_apples_to("beth", 4)}
-> DONE

MinInkExample.cs with compiled story inlined

using System;
using Ink.Runtime;

public class MinInkExample : object
{
    private string storyText = @"{""inkVersion"":11,""root"":[[{""->"":""Begin""},null],""done"",{""Begin"":[[[""G>"",[""ev"",[4,{""x()"":""grow_apples"",""exArgs"":1},null],""out"",""/ev"",null],""G<"",null],""\n"",[""G>"",[""ev"",[""str"",""^beth"",""/str"",4,{""x()"":""give_apples_to"",""exArgs"":2},null],""out"",""/ev"",null],""G<"",null],""\n"",""done"",null],null]}]}";
    public MinInkExample()
    {
        Story s = new Story(storyText);
        s.BindExternalFunction("grow_apples", new Action<int>(GrowApples));
        s.BindExternalFunction("give_apples_to", new Action<string, int>(GiveApplesTo));
        s.ContinueMaximally();
    }

    // OK
    private void GrowApples(int howMany)
    {
        string msg = "you grow " + howMany + " apples.";
    }

    // Throws: System.Exception: Failed to cast String to Int32
    private void GiveApplesTo(string who, int howMany)
    {
        string msg = who + " has " + howMany + " apples.";
    }
}

Randomization in functions

It would be nice to have some form of randomization within functions. I was hoping something like
VAR temp_pos = {~1|2|3|4|5}
would work, but it doesn't seem to be possible using the randomization options used by the printing features.

Read counts in loop

Hello.
Found an issue today with read count (at least, I think that it shouldn't work like this)
If you are making a loop, read count doesn't increase number.
Small example to reproduce this:

=== Beginning ===
How many times he started this story again: {Beginning}
Once upon a time...
+ Where was I?
-> Beginning
* Ah, nevermind. ->END

Beginning always would be 1. And with this small workaround

=== Beginning ===
Once upon a time...
+ Where was I?
-> Times
* Ah, nevermind. ->END
=== Times ===
How many times he started this story again: {Beginning}
-> Beginning

Read count increases correctly. I guess, read count can increase its value only if it comes from another knot, right?

Ink Syntax Specs

As mentioned, I'm tinkering with an Ink implementation in Java, and it sounds like someone else might do something in Javascript (though perhaps it might make sense to join forces for that - depending on the implementation, a JS client could use the Java code).

Anyway, if it's OK, it might be useful to have a thread for questions/clarifications about the script intents. I've already run into a few things which are not covered in the docs.

Stitch definition causes inklecate play mode to exit with a 'ran out of content' message

I run the following test story via the terminal: (inklecate -p myStory.ink).

===once===
Once upon a time there was a story.
= options
*   Read it
*   Ignore it
- The end.
-> END

I get the following output:

Once upon a time there was a story.
Runtime error in myStory.ink line 2: ran out of content. Do you need a '-> DONE' or '-> END'?

If i comment out the '= options' stitch, then it works as expected. It looks like including the stitch is causing a problem.

(OSX 10.11.3 i case it matters)

Some thoughts and comments

Writing here, for lack of any better persistent forum for discussion (chat has the problem that there is no history for guests, thus limiting the discussion to only those who happen to be present at the time of the discussion).

I have to say that the more I study Ink, the more I like it. I have some preferences that are at odds with what you've done (already mentioned), but I really like the expressiveness and succinctness of the script. I am particularly enthused by Weaves and the Knot = Function approach. These solve issues I've struggled with myself, and my own solutions are nowhere near as elegant.

Tempted to take my existing script engine, and making it Ink compatible. Probably keeping it in Java, although I'm rather keen on Kotlin and Scala at the moment. But Java is native to Android, and will also work for a web app (e.g., using the awesome Play Framework). Have other things I need to finish up first, but it's definitely something that I could see a use for myself. We'll see how much time I have.

Some thoughts:

  1. I'm not so worried about the JSON format, but I hope the script syntax and semantics wouldn't be something that would change very much in the near future (other than to add functionality). Otherwise it would be rather hard for people to start using Ink for anything serious.
  2. Some things need to be specced a bit more rigorously. The thing I've noticed right now is the if-then and switch. The text claims that white space doesn't matter, but it's not obvious that this is the case (unless white space = only horizontal white space).

For instance, is:
{ - x > 0: ~ y = x - 1 - else: ~ y = x + 1 }
The same as:

{
    - x > 0: 
        ~ y = x - 1
    - else: 
        ~ y = x + 1
}

Or for that matter:

{  - x > 0: 
        ~ y = x - 1
    - else: 
        ~ y = x + 1 }

Haven't had the time to get this up and running on my Win PC yet, but whether it's only the middle one that is valid or all three are valid, I'd suggest that this is clarified in the docs. These kind of errors suck having to debug (one of my collaborators ran into something like this not long ago).

  1. In general, some test specs would be useful. Understand why you haven't added anything substantial there, especially as you say the specs are still being evolved, but a thing to keep in mind. It will make things much easier for people who wish to work on new runtimes/implementations.
  2. One thing that I think is missing in the repo right now, is a good example Ink script. E.g., you Adventure of the Musgrave Ritual in Ink script and might as well throw in Cloak of Darkness as well. At least in my experience working with OSS, one always wants to make the threshold for adoption/interest as low as possible, and it really doesn't get much lower than saying "here, run this program on this script and see what happens".

Just my 25 cents.

Best of luck at GDC, btw. Hope the Ink talk will be made available; would love to watch it.

Ink does not support accentuated characters

Hi guys,

I've tested the thing in Windows and Inklecast does not support accentuated characters. They are always substituted by a ? character.

In the beginning I though it could be just a thing of the inklecast build in windows, but simply, if I export the source to JSON, the output still does not support that special characters.

So this basically means we could not create games with Ink in any language different than English. That is, no Spanish, no French, no Russian, etc.

That's all, good work, I'm enjoying studying Ink a lot. Regards.

Ink flips parameters in externally bound functions; breaks with three parameters

Okay so I've created a barebones project where I am seeing this issue:

https://drive.google.com/open?id=0BxMWw45YG-83d1Z0ejlBc2VGWnM (hosted on my google drive because github wouldn't let me upload it)

The scene is Scenes/Main; the script is Scripts/MainStory; the Ink is Resources/Ink/Ink. The plugin folder is included along with the unitypackage which was downloaded from here: https://github.com/inkle/ink-unity-integration/releases.

The issue is like the title says. @joethephish said he had seen it before. I should also mention I am on Windows and Unity version 5.3.4f1. Let me know if there is any other relevant info to know about my machine if you cannot reproduce this!

Inklecate crashes when parenthesis are left off of an external function declaration

Reproducable on version 0.2.3 alpha, using windows version of inklecate. Haven't tried with the mac version.

This is the story I used to reproduce:

EXTERNAL bring_the_pain

== CrashMe ==
This is gonna hurt...
+ DONE

Stack trace as follows.

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at Ink.InkParser.ExternalDeclaration()
   at Ink.StringParser.ParseObject(ParseRule rule)
   at Ink.StringParser.OneOf(ParseRule[] array)
   at Ink.InkParser.StatementAtLevel(StatementLevel level)
   at Ink.InkParser.<StatementsAtLevel>c__AnonStorey6.<>m__0()
   at Ink.StringParser.ParseObject(ParseRule rule)
   at Ink.StringParser.Interleave[T](ParseRule ruleA, ParseRule ruleB, ParseRule untilTerminator, Boolean flatten)
   at Ink.InkParser.StatementsAtLevel(StatementLevel level)
   at Ink.InkParser.Parse()
   at Ink.CommandLineTool.<CommandLineTool>c__AnonStorey1.<>m__1()
   at Ink.CommandLineTool.TimeOperation(String opDescription, Action op)
   at Ink.CommandLineTool..ctor(String[] args)
   at Ink.CommandLineTool.Main(String[] args)

Story Variables

Hello, first of all, love this project. Very easy to use!

I'm creating a game that is very moldable, and I was trying to get all variables that were created on Ink and pass to a callback method when the -> END is reach.

I'm having difficult because story.variablesState hides his keys and I can't iterate to get all variables.
Just wan't to know if this has some reason or just that none one had this necessity before. If you're ok, i can modify this, exposing this class's keys.

Compiled ink format requirements and goals

I am currently noodling around with an alternative to the JSON compiled ink format. My current goals are to have small file sizes, faster loading, and no third-party dependencies. However, I'd be keen to know what the original requirements and goals were for the current format so that I can see if my approach could cover those too. For example, the current format is obviously JSON as opposed to a binary format; so the files are easy to parse in alternative languages, are arguably human readable, etc. But if these are not actually requirements of the compiled format then more improvements are possible.

In any case I am still at the experimentation stage so nothing may come of this, but the above info would be handy to document regardless.

Windows line termination

Before I jump in and accept this code comment pull request from @MattConrad, I was just wondering if anyone can help out with the source of the problem?

I'm not a Windows expert, though I understand the differences in line termination between platforms, broadly speaking. To be honest I was relatively surprised that me using \n everywhere worked okay, even when editing a story in Notepad, of all text editors.

Is the .gitattributes file the way to go to ensure Windows doesn't autoconvert, or is there something else we should be aware of? Should we simply being more line-ending agnostic in the compiler itself...? What's the "modern" way of handling this stuff?

Visual Documentation of Stories

Hello,
When I has creating my stories, I felt the need to some sort of visual documentation of the decision path the this stories could take. So I use Astah UML (Activity Diagram) to make this.
Was someone uses another software to make this or has some tips to give?
diagram1

autocomplete disabled in newest update?

Sublime's autocomplete seems to be disabled in .ink files as of the latest build. Manually setting autocomplete to true does not restore the functionality.

If it helps, before build 7222bb2 I was using autocomplete regularly.

Thanks for your help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.