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

Evaluating a path immediately triggers any function and variables in it #21

Open
ZeAntwan opened this issue Sep 16, 2023 · 7 comments
Open
Labels
bug Something isn't working runtime

Comments

@ZeAntwan
Copy link

Hi, I know I might be digging back this library, but I'm happy to try and explore solutions for this!

I've been working on porting this library to work on Playdate (meaning needed some simplification), but I'm also trying to get it to evaluate ink knots/paragraph line by line. While I can get the text to work as expected using the continue(n) function, the problem I have is that any variable that get set in it or any functions that get called, are triggered when the path is jumped to.

This can be tested using the example code and the readme, and calling this "call_911" knot

EXTERNAL phonebook(name,number)
EXTERNAL test(pouet)

=== function phonebook(name,number) ===
// Placeholder for phonebook function
~ return 1

=== function test(pouet) ===
// Placeholder for phonebook function
~ return 1

=== call_911 ===
{call_911 >= 2: I've seen you before... }
You've just called the emergency services
<i>Test</i>
~ test("test")
~ phonebook("Emergency","922")
[i]Test2[/i]
Please don't
We have shit to do 
And this is a very long thing
It should remove some lines from before
Let's hope so
-> DONE
@astrochili
Copy link
Owner

astrochili commented Sep 19, 2023

Hi!

As I understand it, you mean that after calling story:begin() or story:choose(answer) there is a complete internal paragraphs execution with all external functions called, and then the host game can pop paragraphs from the ready-to-read stack. So there is no way to place an external call between paragraph output. Am I right?

@ZeAntwan
Copy link
Author

ZeAntwan commented Sep 19, 2023

Yes, I think that matches the issue I'm having. So far, I've only tried using story:continue() and was expecting that doing story:continue(1) would only process one line, and not the whole paragraph before returning a line. I haven't tried choose to see if something similar happen (but would expect it to after looking at the code and my understanding of it).

And I will double check, but I believe this applies to any kind of variable operation too, so setting a value anywhere in the paragraph, will set the value when the knot is jumped to instead of wait for it to be "read".

In my example, the "phonebook" function should add something only once the line is read, which seems to be the behaviour of most other ink libraries I'm using for C# (but I could be wrong)

(Note: for my specific purpose, I found a workaround using tags, but result in kind of duplicated logic for my use where I would tag a line with the function call to then handle it manually, so not the cleanest or most reliable solution)

@astrochili
Copy link
Owner

That's definitely how it works now. The continue(x) function just returns already prepared paragraphs.

If it doesn't work that way in the other frameworks, it's probably a Narrator design bug 😔.

You can also check out this implementation that works with compiled js files - https://github.com/abadonna/defold-ink/tree/main/ink

@ZeAntwan ZeAntwan changed the title Evaluatin a path immediately triggers any function and variables in it Evaluating a path immediately triggers any function and variables in it Sep 19, 2023
@astrochili
Copy link
Owner

We've had a little chat with @abadonna about this and to be honest, we're not sure if other plugins do things differently.

Yes, it would have to be tested to make that claim. But logical reasoning about the liquid nature of paragraphs, when often without code execution it is not clear where the paragraphs are and where they are not, up to the fact that functions themselves can return a whole set of paragraphs... give the impression that the current behaviour is correct.

And for your idea, indeed, tags are suitable. Or splitting into blocks by an additional intermediate choice, which is "especially" automatically handled in the game. The second way seems to be the most architecturally correct for your example.

@abadonna
Copy link
Contributor

abadonna commented Sep 19, 2023

Just checked the original Unity asset.
If ContinueMaximally() method is called - external function called first, same behaviour as in Narrator.
If Continue() method is called and only 1 paragraph is returned - external function called as @ZeAntwan wants it to be called ...
It's pretty straightforward, story starts to read ink script, and if it needs to return result - story just stops, so in case of single paragraph - it just returned and in case of multiple - every function calls processed and paragraphs are being generating until story finally finds the choice.

@astrochili
Copy link
Owner

Thanks for checking that out.

That's very interesting, sounds like not an obvious difference in behaviour. It turns out if calling continue(1) 3 times is not the same as calling contnue(3) 🤯

On the other hand, Ink has always had room for ambiguity 🙃

@ZeAntwan
Copy link
Author

Thanks for looking into it, and sorry I did not provide the test. I'm using Godot, which uses a port of the Unity/C# implementation of it and that might be what threw me off.

It's always been a fight for me to understand how to "properly" use ink when trying to do adventure or dialogue box bas games that show dialogues line by line.

With that said, like you mentioned, while I still need to go a bit deeper, I might be able to manage using tags for now 🙂

@astrochili astrochili added feature support New feature or request runtime bug Something isn't working and removed feature support New feature or request labels Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working runtime
Projects
None yet
Development

No branches or pull requests

3 participants