-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Is your feature request related to a problem? Please describe.
With YarnSpinner the [select] markup is frequently used for gendered cases, where a variable or function supplies a value so the line can be adjusted based on a characters gender. This workflow breaks if an additional localization needs that gender value for a line where the [select] markup wasn't used in the base localization.
As an example, this line would be in the base English [en] localization:
// the neighbour's gender here could be male, female, or non-binary
// but that context isn't needed for this line
Hey neighbour!
But in a more gendered language like French [fr] it would need to be:
// $neighbourGender here has the value of the neighbour's gender
Salut [select value={$neighbourGender} m="voisin" f="voisine" nb="voisin"/]!
Though the [fr] localization will not render the markup correctly since the value for $neighbourGender is never used in the base localization, and as a result the LocalizedLine.Substitutions array won't have a value for it. There isn't a built in way to request additional substitutions for inline values that don't appear in the base localization.
Describe the solution you'd like
Ideally the [select] markup should work as written in the [fr] localization, meaning the values for LocalizedLine.Substitutions will be populated based on inline variables in the current localization text and not just the base localization.
Maybe some sort of markup to signal to the LineProvider that this line is requesting additional data that isn't present in the base localization's Substitutions array, and be able to handle that accordingly.
Otherwise some sort of solution that is available for developers to implement and isn't a massive departure to the markup workflow for translators. The root of the problem is there isn't a way to use YarnSpinner's built in markup to handle these localization issues, the solution doesn't necessarily have to be YarnSpinner markup.
Describe alternatives you've considered
This was discussed on the Discord server, but all of these are workarounds.
A simple hack is to just find a way to get that data into the Substitutions array, adding the replacement markup in the base localization even though it doesn't need it. So writing this line in [en] will ensure the above [fr] line works:
Hey [select value={$neighbourGender} m="neighbour" f="neighbour" nb="neighbour"/]!
Or just adding any markup like a custom self closing one, just so the variable gets thrown in:
// [noop] here does nothing
Hey neighbour! [noop={$neighbourGender}/]
This is only a viable solution for a couple lines, and is unreasonable for larger projects. This also requires the base localization to be modified for other locals to work, which either means foresight into the grammatical rules for the projects other locals or unplanned edits to the base local.
Its also possible to create a custom Line Provider to parse the raw string value to fetch the additional data the current local needs that's absent in the Substitutions array. This is the best general solution.
If there is only one character that has a variable gender, such as the player in the story, then a custom Line Provider can load additional lines that are only affected by the gender per localization. The Line Provider will check if a specific gendered version of the line matching the gender variable exists and supply that instead and default to the normal line otherwise. Though this only works for one variable (gender in this case), if the local needs additional grammar rules that doesn't exist in the base localization this can get unwieldy.
The last solution is to use a custom markup that can behave like the [select] markup, but its value attribute is a flag to fetch a value. This means that the Presenter, Line Provider, or some other component needs to handle this value fetching and render the markup correctly.
Additional context
I want to emphasize that the issue itself isn't the [select] replacement markup, while its primarily used for gender cases in this issue report the markup tag itself is amazingly flexible and adaptable. It makes no assumptions about the input data so it can be used in many different cases, I personally used it with random values like dice() to have cycling text before line groups were introduced in YS v3.
I also want to discourage some sort of purpose built solution for gender cases, even though this issue focuses on them. Some languages have grammar rules for not just gender, but also the amount of people, age of the subject and/or relative to speaker, familiarity, status, formality, time of day, etc. So if there was a markup solution just for gender cases then there would still holes for those languages. The [select] markup can handle all of those cases if the localization that requires it can get the data.