-
-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Proposal: ability to call a node and return to the next spot in execution #303
Comments
Originally I was more in favour of this, however as the language has evolved and grown in that time and as we see more people use it I am less enamoured with this as an idea. Back at the time I said I think embedding is a better idea over returns and I still hold that view now, just more strongly. The main downside to embedding is an embedded node won’t really be visited as such as it will more or less just be dumped straight into the guts of another node, so lines like Additionally if the embedded node has a jump inside that will essentially close the embedding node as well as the embedded node.
tldrI think supporting node embedding, that is to say dumping the contents of a node inside another one, is a better option than embedding that covers most (if not all) the situations where you want nodes to return. Embedding has some concerns to be worked out but these are not hugely difficult and either require clear messaging in documentation around embedded usage or some compile time variable tracking. The syntax for this would be either |
So like you would |
Pretty much yes, albeit one without the weirdness of the C linker if possible… |
|
I don't know, I still really like the original plan. Making a special type of node that looks normal but doesn't ever get marked as visited or other behaviours you expect of nodes I think is strange, and you can see how representations of this in things like the Yarn editor would be confusing. I know we did away with And the times I have wished for such a functionality have been things like:
|
And the power I foresee of Honestly, these arguments all lead to the same logical conclusion though: arbitrary jumps. Like in languages where you can mark
that would be even better. |
I agree that suggesting Ink's documentation on Tunnels seems to solve this issue pretty well. Their solution (if translated to Yarn), would be to allow |
However it's probably worth mentioning here that Ink also has a pretty good grasp on hierarchical structures (e.g. "stitches" which are basically sub-nodes), which arguably goes hand-in-hand with To me, the use of |
Yeah sorry I think I spoke a bit too negatively about the edges cases of embeds, in fact almost every edge case of the embed also applies to the returns as well, I was just trying to list them for discussion. Likewise you could allow nested embeds and jumps from embeds I just think it invites spaghetti dialogue, not that they couldn't be done, which is why I was initially against allowing this. As to Mars' suggestion of arbitrary jumps into nodes I am very much against this. |
Maybe there could be a compiler configuration to allow for advanced modes, one to allow for embeds, another to allow for embeds that allow for additional embeds and jumps. spaghetti mode and spaghetti with meatballs mode (probably could use better names haha)? This could keep the default to what is most straight forward for writers and for those who would like to have more control then it can be set in the Yarn Project file. I effectively used embeds for Button City for world set up and while I'm going to be changing how I architect our next game I still think having these types of options would be really useful. I should also note that my implementation also had it track that the node was visited. |
Developing an Adventure/VN type game atm I would very much like to simply be able to embed nodes to keep the "logic" nodes concise and to the point.
It would decouple developing the logic from the writing process more clearly by both not having to scroll up and down in the other file/text. It's easy enough for simple logic as is but having multiple and more complex gamestates it gets very unwieldy and confusing to jump around nodes, keep the scheme in mind and find everything... |
And embedded nodes should be placed at the indention level where the command is found, if that's not already on the radar ;) |
Embedding sounds dangerous in case there are circular references. I.e. "Node A embeds Node B which embeds Node C which embeds Node A". If the embedding is done lazily in runtime, then this may not be an issue but important to keep in mind... |
@Haapavuo Unless embedded nodes forbid further embeds that is very much true. As it would be for gosub-return. What would be the consensus on how to ease developers pain in the scenario I described? We'd very much take embedding that prohibits further embedding for usability/writeability reasons. Even better would be embedding that crawls all further embed found and throws an error if it detects circularity. Not simpel but doable and a good solution, no? Add "It is just simpler if an embed has a clear in and out which is only realistically possible if you don't allow jumps inside them." and it sounds golden to me. |
Yeah the fear of cycles was exactly why I initially said the best option would be to just ban embeds inside of an embed node. There was a decentish amount of pushback against no allowing embeds so that would mean performing cycle detection. This isn’t impossible and I reckon the easiest way (at least initially) is to just do a small limit on embedding depth, somewhere in the region of 3 to 5 I reckon. A jump would still be allowed because a jump removes all previous context and starts fresh on the jumped node. |
Was thinking about this some more yesterday and I would solve this with a recursion that crawls through all embeds in a project and checks the branches for back-embeds via lists of nodes. I'd do this check at compile time but then again I'm not very familiar about Yarns structure and flow. As I'm also currently not that fluent with c# I better not volunteer to dev that. As my lecturer at uni said in the 90s "recursion to the rescue!"... |
It seems the discussion mostly centers around whether we should do embeddings or jump-and-returns. It would be beneficial then to lay down what exactly each option mean, and how it would solve existing (and future) use cases.
Thus, there appears to be quite a significant number of differences between these two options, especially in how they could evolve in the future. Which makes choosing between the two difficult. Luckily, we don't actually have to choose -- we can implement both. |
Seems it calls for a classic pro/con comparison of the two. Effort to implement and maintain, amount of advantage for devs and so on. |
Jump and return seems like a natural choice to me, with much more alternatives for flow control. However, it does appear to be a more complex implementation compared to embedding. Considering the trade-offs, if the implementation cost of jump and return proves to be prohibitive, embedding can be a sufficient solution for many cases. |
This feature has been announced as part of Yarn Spinner 3.0. Thanks for all of the discussion, everyone - this thread was extremely useful in guiding the final implementation of the feature. |
Issue #92 by @rcuddy proposed adding functionality to the jump command that told the runner to return to the callsite once that node completed. There were several proposals for syntax surrounding the jump command, primarily
[[NodeName]] #return
. @rcuddy made a fork with the functionality implemented, but this was not merged as it coincided with the Yarn migration to ANTLR.Issue #264 by @McJones proposed changing the
[[Text|NodeName]]
syntax to-> Text <<jump NodeName>>
and assumed the discussion of the return functionality when @desplesda proposed including syntax for<<jump NodeName return>>
. When the ANTLR migration was complete and the jump syntax changed, Issue #264 was closed and the discussion of return died with it.This issue opens new discussion about return.
Example with Updated Syntax
Discussion Thus Far
@McJones asked and @desplesda answered:
Does this count MorningRoutine as having been visited? Yes, I'd count the node you've just run as having been listed.
Do we allow nested embedding? Yes, I'd allow nesting this behaviour. All we'd need to do is maintain a stack of return addresses.
Do we report we are in a different node or are we still inside the calling node? I'd report that we're in a different node.
Do we do embedded node cycle detection? We don't currently detect or report on the cycles that are possible already (example: Node A can say
<<jump NodeB>>
, and Node B can say<<jump NodeA>>
. If we add cycle detection, I don't think it would need to have any special considerations for this functionality.@rcuddy responded to the same questions with very similar views.
The text was updated successfully, but these errors were encountered: