commit 3d6802add8
Author: Dav999 <dav999.tolp@gmail.com>
Date: Thu Oct 19 17:16:01 2023 +0200
Change AVOID to FAINIC in Irish
commit 21fd84f479
Author: Dav999 <dav999.tolp@gmail.com>
Date: Thu Oct 19 17:04:27 2023 +0200
Partial final strings for Esperanto
This does not yet include the new localization credits, but I already
had all the other strings.
commit 45382a358c
Author: Dav999 <dav999.tolp@gmail.com>
Date: Thu Oct 19 17:01:30 2023 +0200
Final strings for Dutch
I also decided to change AVOID from ONTWIJKEN to ONTWIJK, to make it
a bit more fitting as if it's an actual word enemy with length
restrictions, heh. (Not that it's an abbreviation - it's just an
imperative instead of an infinitive. And those terms I had to look up)
Well, 100% up-to-date with current upstream at least, there's some more
strings to be added soon, including "{area}, {time}" from #1018, a new
menu option related to translatable graphics files, and definitely some
credits stuff.
These were causing false alarms in translations for one reason or
another (either to force translations to not wordwrap for style
reasons, or to stay on the safe side if an adjacent string was also
long), so they can be raised now.
I really thought I was going to need to block changing the language
in-game altogether, but activity zone prompts are now fixed and the
only obvious problem I can think of right now is having a dialogue
open, so I just disable the language option if a textbox is displayed.
(like how the map menu only has the save option if a script is running)
This adds the following new strings from #993:
- The level editor is not currently supported on Steam Deck, as it
requires a keyboard and mouse to use.
- The level editor is not currently supported on this device, as it
requires a keyboard and mouse to use.
Unfortunately this means most languages won't be quite 100% anymore
for a bit, and updates come in which don't have this string yet.
But at least we can track it really well. In the next couple of
commits, when a language is updated with all new strings except for
these, I'll call them 99.9% instead of 100% (I did not get an actual
percentage).
Two changes:
- The labels on the Game Complete! screen for number of trinkets/deaths
/time etc have been moved two pixels to the right, and had their
limits increased by 1 character
- The inaccuate limit for "quit to main menu" has been increased
A little while ago the term "AGOKLAVO" (action-key) was chosen to
replace the older "AGBUTONO" (action-button). However, in a recent
language update, I mistakenly used the older term in a new string.
This has been fixed.
Also note that it's written in the accusative case for this string
(with an "N" suffixed) since it is always used as the object of the
sentence where it appears ("Premu AGOKLAVON..." = "Press ACTION...").
This adds a "- Press {button} to skip -" prompt to both the credits and
ending picture sequences.
It was always possible to skip them by pressing Enter, but not many
people knew this. In fact, even I didn't know this until I saw Elomavi
do it a year or so ago. So it's not really intuitive that this is
possible.
The prompt only shows up if you've completed the game before, and
disappears after two seconds similar to the "[Press {button} to return
to editor]" text.
Unfortunately, given how the game works, game completion is detected
based on if you have unlocked Flip Mode or not. At this point, the
unlock for the game being completed (unlock 5) will already be set to
true no matter what during the Plenary fanfare, but the Flip Mode unlock
(unlock 18) won't be until the player hits "play" on the main menu. As a
special case, the prompt will always show up in M&P (because Flip Mode
is always unlocked in M&P).
2.3 already made it so that if you ran the `rollcredits` command during
in-editor playtesting, you wouldn't be returned to the title screen
while losing unsaved level changes. But there are plenty of other ways
to go back to the title screen from in-editor playtesting too. Namely,
gamestate 1015 (the gamestate after completing a level) and 82 (time
trial complete).
So just add the appropriate checks to those gamestates, and add a
catch-all check in Game::quittomenu(). Additionally,
Game::updatecustomlevelstats() should not update custom level stats
during in-editor playtesting (otherwise it would still happen even if
the game didn't bring you back to the title screen).
Editor notes will also be shown if the game prevents you from going to
the title screen.
Also, just to make things clear, I also added a level note for when the
level is completed during in-editor playtesting. This is just to make it
clear in cases where it might not be obvious that the game returned you
to the editor for this reason. E.g. you have a terminal that calls
gamestate(1013) in a level with 0 custom crewmates, but when you
activate it, it looks like the terminal didn't work for some reason and
just brought you back to the editor. But that's just only because you
literally just completed the level.
This will actually do several things:
(1) Make the tile size checks apply to the appropriate graphics files
once again.
(2) Make the game print a fallback error message if the error message
hasn't been set on the levelDirError error screen.
(3) Use levelDirError for graphics errors too.
(4) Make the error message for tile size checks failing specify both
width and height, not just a square dimension.
(5) Make the error messages mentioned above translatable.
It turns out that (1) didn't happen after #923 was merged, since #923
removed needing to process a tilesheet into a vector of surfaces for all
graphics files except sprites.png and flipsprites.png. Thus, the game
ended up only checking the correct tile sizes for those files only.
In the process of fixing this, I also got rid of the PROCESS_TILESHEET
macros and turned them into two different functions: One to make the
array, and one to check the tile size of the tilesheet.
I also did (2) just in case FILESYSTEM_levelDirHasError() returns false
even though we know we have an error.
And (3) is needed so things are unified and we have one user-facing
error message system when users load levels. To facilitate this, I
removed the title string, since it's really not needed.
Unfortunately, (1) doesn't apply to font.png again, but that's because
of the new font stuff and I'm not sure what Dav999 has in store for
error checking. But that's also why I did (4), because it looks like
tile sizes in font.png files can be different (i.e. non-square).
This exports the previously-internal setLevelDirError function in
FileSystemUtils and uses it for if a level is not found or there was a
parsing error. Previously, if a level failed to load in these ways, it
would take you to the error screen with no error, while printing it to
the console. But this makes it more user-friendly.
As a bonus, the text is localizable, just like the existing usage of
FILESYSTEM_setLevelDirError for if a path couldn't be mounted.
In Italian, "Credits" is "Riconoscimenti", which runs offscreen with
the 3x font size that this title uses in the rolling credits at the end
of the game. I'm not sure if the translators saw that specific
instance, or thought the limit complaint was about the main menu button
all along (which is more prominent and *does* stick out far enough that
the complaint could plausibly have been about that, from a translator's
perspective!)
Either way, it's solved now: this string's width is now checked, and if
it will run offscreen at 3x size, it will now be displayed at 2x size
instead. The limit has been increased from 13 to 20 in the language
files accordingly.
The language screen has a "Press Space, Z, or V to select" hint, which
I forgot to update for supporting button glyphs in #943, so this commit
does.
<action_hint>Press Space, Z, or V to select</action_hint>
<gamepad_hint>Press {button} to select</gamepad_hint>
This was easier than I expected - just add an optional buttons="1"
attribute to cutscenes.xml. It's treated like the speaker attribute -
it's only there as context for the translator, and for the cutscene
test.
Due to rebasing messiness and diff noise, it's probably best if pull
requests either don't sync all the language files at all (and only
modify the English ones) OR only do it as a final commit. It's still
something we need to figure out, lol.
This updates all language files to the latest version.
- Some minor errors are also fixed - for example, a small number of
changes were made to the English string instead of the translation.
Alignment of the dimensional stability generator terminal is also
improved in several languages.
- I also discovered that the string "Complete the game" appears twice -
and has, to be consistent with adjacent strings, two separate
translations in Portuguese (PT). So this string now properly has two
different cases so it can be translated separately.
- The limit for TIME/SHINY/LIVES has been bumped from 7 to 8
The following languages are new:
- French
- German
- Italian
- Portuguese (BR)
- Portuguese (PT)
- Russian
- Spanish
- Turkish
Esperanto has also received some updates.
"by {author}" is a string that will cause a lot of localization-related
problems, which then become much worse when different languages and
levels can also need different fonts:
- If the author name is set to something in English instead of a name,
then it'll come out a bit weird if your VVVVVV is set to a different
language: "de various people", "por various people", etc. It's the
same problem with Discord bots completing "playing" or "watching" in
their statuses.
- Translators can't always fit "by" in two letters, and level creators
have understandably always assumed, and will continue to assume, that
"by" is two letters. So if you have your VVVVVV set to a language that
translates "by" as something long, then:
| by Various People and Others |
...may suddenly show up as something like:
|thorer Various People and Othe|
- "by" and author may need mutually incompatible fonts. For example, a
Japanese level in a Korean VVVVVV needs to be displayed with "by" in
Korean characters and the author name with Japanese characters, which
would need some very special code since languages may want to add
text both before and after the name.
- It's very possible that some languages can't translate "by" without
knowing the gender of the name, and I know some languages even
inflect names in really interesting ways (adding and even replacing
letters in first names, surnames, and anything in between, depending
on gender and what else is in the sentence).
So to solve all of this, the "by" is now replaced by a 10x10 face from
sprites.png, like a :viridian: emote. See it as a kind of avatar next
to a username, to clarify and assert that this line is for the author's
name. It should be a fairly obvious/recognizable icon, it fixes all the
above problems, and it's a bonus that we now have more happy faces in
VVVVVV.
By default, when you open the level editor to start a new level, the
level font will now match your VVVVVV language; so if you're, say,
Japanese, then you can make Japanese levels from the get-go. If you
want to make levels for a different target audience, you can change the
font via a new menu (map settings > change description > change font).
The game will remember this choice and it will become the new initial
level font.
meta.xml can now have a <font> tag, which gives the name of the font
that the language needs. This will directly control the interface font
when the language is active, and will soon also control the font used
for each option on the language screen.
This allows translators to test all text boxes in the scripts. It
doesn't run the scripts themselves - it only shows the basic appearance
of each text box individually, so context may be lost but it's good to
have a way to see any text boxes that might otherwise not be easily
seen because they require specific circumstances to appear.
The strings "Vitellary"/"Vermilion"/"Verdigris"/"Victoria" now have two
cases to support changing them for the intermission replay menu options
(like "with Vitellary").
Also, the string "< and > keys change tool" is now "{button1} and
{button2} keys change tool", so it can be changed dynamically without
having to retranslate the string.
I wanted to not complicate the system with different string cases (like
cgettext) if possible, and I have been able to keep the main strings a
simple English=Translation mapping thus far, but apparently strings
like "Rescued!" (which are one string in English), have to be
translated for the correct gender in some languages. So this was a good
time to add support for string cases anyway.
It's a number that can be given to a string to specify the specific
case it's used, to disambiguate identical English keys. In the case of
"Rescued!" and "Missing...", male versions of the string are case 1,
female versions are case 2, and Viridian being missing is case 3. Of
course, if a language doesn't need to use different variants, it can
simply fill in the same string for the different cases.
If any other string needs to switch to different cases: distinguish
them in the English strings.xml with the case="N" attribute (N=1 and
higher), sync language files from the translator menu (existing
translations for the uncased string will simply be copied to all cases)
and change loc::gettext("...") to loc::gettext_case("...", 1),
loc::gettext_case("...", 2), etc.
I would, of course, recommend translators to translate the roomnames
while playing the full game (optionally in invincibility) so they can
immediately get all the context and maybe the most inspiration. And if
you want to go back into a specific level, then there's always the time
trials and intermission replays which will give you full coverage of
all the room names.
However, the time trials weren't really made for room name translation.
They have some annoying features like the instant restart when you
press ENTER at the wrong time, they remove context clues like
teleporters and companions, but the worst problem is that the last room
in a level is often completely untranslatable inside the time trials
because you immediately get sent to the results screen...
So, I added a new menu in the translator options, "explore game", which
gives you access to all the time trials and the two intermissions, from
the same menu. All these time trials (which they're still based off of,
under the hood) are stripped of the annoying features that come with
time trials. These are the changes I made to time trial behavior in
translator exploring mode:
- No 3-2-1-Go! countdown
- No on-screen time/death/shiny/par
- ENTER doesn't restart, and the map menu works. The entire map is also
revealed.
- Prize for the Reckless is in its normal form
- The teleporters in Entanglement Generator, Wheeler's Wormhole and
Level Complete are restored as context for room names (actually, we
should probably restore them in time trials anyway? Their "press to
teleport" prompt is already blocked out in time trials and they do
nothing other than being a checkpoint. I guess the reason they were
removed was to stop people from opening the teleporter menu when that
was not specifically blocked out in time trials yet.)
- The companions are there at the end of levels, and behave like in no
death mode (become happy and follow you to the teleporter). Also for
context.
- At the end of each level, you're not suddenly sent to the menu, but
you can use the teleporter at your leisure just like in the
intermission replays. In the Final Level, you do get sent to the menu
automatically, but after a longer delay.
I made another mark on VVVVVV: don't be startled, I added gamestates.
I wanted all teleporters at the end of levels to behave like the ones
at the end of the intermission replays, and all handling for
teleporting with specific companions is already done in gamestates, so
rather than adding conditional blocks across 5 or so different
gamestates, it made more sense to make a single gamestate for
"teleporting in translator exploring mode" (3090). I also added an
alternative to having to use gamestate 3500 or 82 for the end of the
final level: 3091-3092.
One other thing I want to add to the "explore game" menu: a per-level
count of how many room names are left to translate. That shouldn't be
too difficult, and I'm planning that for the next commit.