-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[ENHANCEMENT] Prepare previously Hard-Coded Texts for Localization Support #3985
base: develop
Are you sure you want to change the base?
Conversation
I like |
I see, looks quite interesting and pretty much covers everything from this pr. However I noticed the "needs revision" label and I'm curious as to whether you're referring to the checklist of things that I could do (which is mostly just more hooking up texts) or something else entirely. Also should I keep this to only soft-coded intro sequence since FireTongue obviously cannot cover that and it would be somewhat useful for modders? |
Firetongue + Polymod has a way of handling asset files (like EDIT: I still like FunkinText, so I'll probably just cherry pick that when I get around to it. |
This PR appears to have merge conflicts. Please fix them! |
WAIT!!! HAXEUI ALREADY HAVE A LOCALIZATION TOOL!!! |
We'd probably use that for the chart editor and use Polymod's system for other stuff. |
If this PR gets rejected, then I'd love to see |
Description
Inspired by a comment by Eric about the translations being lower in the priority list due to some obstacles. This PR aims to well overcome those obstacles
It introduces a new class,
FunkinText
, which is an extension ofFlxText
. Basically what it does is every time text (or font!) get updated, it checks whether or not the current font has glyphs for all the characters in the text. If not, the fontArial
is used (subject to change maybe i dunno lol), as it is supposed to have most of the characters due to often being the default fontThis PR also hooks up a lot of previously hard-coded texts to a single .json file,
texts.json
. It's placed exactly whereintroText.txt
is, in theassets/data
folder. Eric mentioned in the comment linked above that Polymod has been upgraded with a locales feature, so now every time a locale is loaded, it should also load thetexts.json
file for that locale, so voilla, translation support hell yeah!Contents of the JSON file
The
texts.json
file is split into two "groups" per se - "title" and the rest.The "title" part
The "title" part refers to the sequence that happens at the start of the game - basically making it soft-codeable now. It has two fields,
"randomTextSplitter"
and"texts"
."randomTextSplitter" is a String Field that dictates what the wacky random texts are split by - defaulting to "--". This means that the texts in the introText.txt file are split by "--" to indicate a line break.
The field "texts" is an array of anonymous structures, with required fields being "beat" and "command". "beat" represents at what beat should the command happen and is an integer value. "command" is basically what should happen when the "beat" happens. It's possible values are:
The optional values to the anonymous structure are "texts", which is an array of strings representing what texts to display, if at all, and "randomText", which is an integer value indicating which part of the randomly chosen line (separated via randomTextSplitter!) to show, if at all. Random Lines have a higher priority than "texts"!
The rest
Alright now for the rest part. This one is a little more tricky. Basically because I could not stand making three gajillion predetermined typedefs for text organisation, so the data from the texts.json file is actually a Dynamic value! That means that any organisation of texts is entirely dependant on the person and it won't toggle any errors! For example, this is an excerp of the .json file with previously hard-coded texts related to freeplay menu
Lets say we want to get the text from the field "ost". To do that, we would simply need to use
Texts.instance.getText("freeplay/ost")
. The slash is indicative of the subgroups n shit. Though be aware! If the command doesn't detect either of the fields "freeplay" or ost (nested inside "freeplay") or if "freeplay/ost" is not a string, it returnsnull
! This system is great for null checks and keeping my sanity in place!A keen eye might have noticed "${value}". That is a macro more or less. So basically some texts require additional fields to operate, like the charSelectHint text with the control. The macro is there so that it could automatically be replaced with a replacer. To get a text that should have a replacer, simply run
Texts.instance.getText([daPath], [daArrayOfValues])
. In this case, if we run the aforementioned command with the values ["balls"] we would receive the text "Press [ balls ] to change characters"!One may wonder why the replacer values are an array instead of a dynamic value. Simply put, during my research to put in as many hard-coded texts I came across one text that required TWO values, eeyikes! To combat it, I had to use arrays. Though what about the macros, one may wonder. Worry not because I have a solution!
Let's say we have a text
Pico Erect was played by pico-christmas
at the location "test/results". Now we could replace "Pico Erect" and "pico-christmas" with the aforementioned macro ${value}, though they both would be linked to one value. If we instead did${value1} was played by ${value2}
we now have macros for two values! And if we want to get the text, we would runTexts.instance.getText("test/results", ["Pico Erect", "pico-christmas"])
. By doing so, we get exactly what we would needed! Hooray!!Additional Things that I could do but I'm not sure whether or not I should do that
Conclusion
tired af lol anyways if any of this was too confusing to you take a gander at the
texts.json
file and the code! Perhaps it would be more understandableill add footage later kinda busy atm