YarnSpinnerTool / YarnSpinner

Yarn Spinner is a tool for building interactive dialogue in games!
https://yarnspinner.dev
MIT License
2.3k stars 201 forks source link

Proposal: Self-closing markup for new line #347

Closed McJones closed 7 months ago

McJones commented 1 year ago

Introduction

This proposal is essentially the opposite approach to #339, so instead of allowing multiple lines of dialogue to be merged we create a markup that allows a single line to be presented as split.

Rationale

In #339 the rationale presented was to solve a common issue of including line breaks inside the source code to make the dialogue be presented across multiple lines on the screen. Changing the parser to handle this however is a complex task but we can achieve the same result with a text replacement markup instead.

Proposed solution

The creation of a new self-closing text replacement marker [br/] (name to be decided later) that expands to an appropriate line break depending on the presentation environment. For example in TextMeshPro this would be expanded to a <br> tag, in ysc this would become a \n. This will require modification to the various dialogue views in YarnSpinner-Unity and related projects.

Backwards Compatibility

No issues because unknown markers are removed by the markup system so will have no impact on existing dialogue.

Alternatives considered

The process and discussion in #339

Acknowledgments

Thanks to everyone who was part of the discussion about this in #339!

st-pasha commented 1 year ago

I believe #339 proposal is a bit different from this one.

In #339, the idea was that sometimes dialogue lines are too long, and it may become uncomfortable to write them on a single line in yarn script (whereas they should be treated as a single line in the game). For example, instead of

Bob: This is a very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very long line!

one could write

Bob: This is a very, very, very, very, very, very, very, very, very, very, very, \
     very, very, very, very, very long line!

I have seen plenty of arguments in favor of 80-character or 100-character line limits to know that there are people who strongly prefer having lines of limited length, so the backslash-newline escape sequence would have accommodates those people's preferences.


This proposal, however, addresses a different need: the ability to insert newlines (paragraph breaks) into the text which is being spoken by a character.

While I like the proposed [br/] markup token, an even simpler solution could be to enable the \n escape sequence:

Alice: Dear Anna,\nI'm writing to you with the concern ...

Note that once we start considering dialogue lines that are so long they require explicit paragraph breaks, it becomes even more important to have some ability to write them as a multi-line entry. And I'm afraid even \⏎ escape won't be sufficient anymore. We may consider something like

Alice: (
  Dear Anna,

  I'm writing to you with the concern that lorem ipsum no longer dolor sit amet.
  And so consectetur, all of the elit now stopped being adipiscing. This is truly
  a disaster, and we're doing our utmost to resolve it as soon as possible. ...
) #hashtag

or (yaml-like)

Alice: |
  Dear Anna,

  I'm writing to you with the concern that lorem ipsum no longer dolor sit amet.
  And so consectetur, all of the elit now stopped being adipiscing. This is truly
  a disaster, and we're doing our utmost to resolve it as soon as possible. ...
  #hashtag

or something like that.

McJones commented 1 year ago

I can't speak for anyone else on the team but I am in general against splitting up single lines into multiple lines. It requires new syntax and the easiest way to do that (and even the examples given) require start and end terminals which are very messy.

The main reason you want to break up a line is so that it it shown broken up in this manner on the view end (as is mentioned in the rationale for #339). If it is a display issue on the editor side that is the concern, setting a line wrap length feels like a much easier solution than adding new syntax. Especially when that feature already exists in pretty much every editor of choice and especially in VSCode.

st-pasha commented 1 year ago

I can't speak for anyone else on the team but I am in general against splitting up single lines into multiple lines.

I agree that having a single physical line per dialogue line is a perfectly reasonable and easy standard. I like it too. However, we could ask: are there other circumstances or users who would find this too restrictive? I can think of a few examples:

Ok, so perhaps this feature could be useful for some niche cases. The next question then -- how hard it is to implement? Speaking of the \⏎ escape specifically, it appears that all that is needed is to add a single line into the lexer's TextEscapedMode:

TEXT_ESCAPED_NEWLINE: \n\s* -> skip, popMode;

Of course, there's also documentation and tests, but overall this looks like a low-effort feature.

For the true multiline dialogue lines, the implementation would be more complicated, and will probably need some changes on the parser's side as well. So I agree that it would be more of a challenge (but still, it could be a welcome feature for some text-adventure games that use very long text pieces for narration). Here's another option from the syntax perspective, using double ::

Alice::
  Dear Anna,

  I'm writing to you with the concern that lorem ipsum no longer dolor sit amet.
  And so consectetur, all of the elit now stopped being adipiscing. This is truly
  a disaster, and we're doing our utmost to resolve it as soon as possible. ...
  #hashtag
McJones commented 7 months ago

Fixed via https://github.com/YarnSpinnerTool/YarnSpinner-Unity/commit/52d2a6a8a0c5fe8aa5600580449759be759ee10c