Bug in UnloadLanguage + fallback strings
6 years 1 week ago - 6 years 1 week ago #3359
by bkane
Bug in UnloadLanguage + fallback strings was created by bkane
I've come across what I believe is a bug in the language unloading behaviour, which may be related to
inter-illusion.com/forum/i2-localization...on-missing-on-device
. This is a bit complicated to explain, but here goes.
Setup:
- Unity 2017.4.9f1
- I2Loc 2.8.9 f1
- Windows 10
- All Google Sheet behaviour disabled ("Never" check frequency).
- Unload languages at runtime: "Device only" (or "Editor and Device")
On Windows, in the standalone player, the data for each language is written to file by Export_Language_to_Cache during startup. This results in files in Application.temporaryCachePath, which is %TEMP%\[companyname]\[productname] on disk. It is during this save-to-disk process that the fallback string for terms with no translations is also determined (and saved both in memory and in the disk cache). However, the fallback will fail to find other languages if they have already unloaded, which happens only if the cache files already exist.
Here's how this works. The very first time you run the game, the cache files do not exist. This is roughly the flow during startup:
1. Sources are added from the I2Languages asset
2. All langauges are set loaded=true
3. The initial language is set as the current language
4. A call to LoadLanguage is made
5. A call to unload all languages other than the current language is made
- This returns early (without unloading), because there is no cache file yet. Languages will not unload unless there is a cache file. See LanguageSource_Language.UnloadLanguage(), line 283: !PersistentStorage.HasFile(PersistentStorage.eFileType.Temporal, GetSavedLanguageFileName(languageIndex)
6. Languages get saved, and Export_Language_to_Cache is called for each language
- As each language is exported, any missing terms are filled in with fallback values.
- These fallback values are found in other languages, because everything is still loaded
- The current language gets fallback values filled in, both in memory and in the written cache file
7. UnloadLanguage is called again, and this time succeeds.
For any subsequent launch of the standalone player, this happens instead:
1. Sources are added from the I2Languages asset
2. All langauges are set loaded=true
3. The initial language is set as the current language
4. A call to LoadLanguage is made
5. A call to unload all languages other than the current language is made
- This time, the languages ARE unloaded successfully (because a cache file exists on disk).
6. Languages get saved, and Export_Language_to_Cache is called for each language
- As the current language is exported, any missing terms are filled in with fallback values.
- However, the other languages have been unloaded, so fallbacks are no longer available
- Terms with missing translations are now stuck with empty translations
- This is also written to disk. You can see the cache file is updated and all "[i2fb]" strings are removed. In practice, this does not matter because the language is never actually imported from these cache files (with these settings).
7. For completeness, UnloadLanguage is called again, though languages are already unloaded.
Note that the Editor behaves differently, as it clears the cache files from disk whenever you exit Play Mode. These means you can get some unintuitive behaviour if you play in Editor after playing Standalone (because there are cache files when usually they have been deleted), or by playing Standalone after playing in the Editor (because cache files will have been deleted, which puts you into the "first time" scenario above).
I totally understand that this might not be clear! The important bit is that the UnloadLanguage behaviour in step 5 above differs based on whether or not these cache files exist, which in turn affects how fallback translations are determined in step 6.
Setup:
- Unity 2017.4.9f1
- I2Loc 2.8.9 f1
- Windows 10
- All Google Sheet behaviour disabled ("Never" check frequency).
- Unload languages at runtime: "Device only" (or "Editor and Device")
On Windows, in the standalone player, the data for each language is written to file by Export_Language_to_Cache during startup. This results in files in Application.temporaryCachePath, which is %TEMP%\[companyname]\[productname] on disk. It is during this save-to-disk process that the fallback string for terms with no translations is also determined (and saved both in memory and in the disk cache). However, the fallback will fail to find other languages if they have already unloaded, which happens only if the cache files already exist.
Here's how this works. The very first time you run the game, the cache files do not exist. This is roughly the flow during startup:
1. Sources are added from the I2Languages asset
2. All langauges are set loaded=true
3. The initial language is set as the current language
4. A call to LoadLanguage is made
5. A call to unload all languages other than the current language is made
- This returns early (without unloading), because there is no cache file yet. Languages will not unload unless there is a cache file. See LanguageSource_Language.UnloadLanguage(), line 283: !PersistentStorage.HasFile(PersistentStorage.eFileType.Temporal, GetSavedLanguageFileName(languageIndex)
6. Languages get saved, and Export_Language_to_Cache is called for each language
- As each language is exported, any missing terms are filled in with fallback values.
- These fallback values are found in other languages, because everything is still loaded
- The current language gets fallback values filled in, both in memory and in the written cache file
7. UnloadLanguage is called again, and this time succeeds.
For any subsequent launch of the standalone player, this happens instead:
1. Sources are added from the I2Languages asset
2. All langauges are set loaded=true
3. The initial language is set as the current language
4. A call to LoadLanguage is made
5. A call to unload all languages other than the current language is made
- This time, the languages ARE unloaded successfully (because a cache file exists on disk).
6. Languages get saved, and Export_Language_to_Cache is called for each language
- As the current language is exported, any missing terms are filled in with fallback values.
- However, the other languages have been unloaded, so fallbacks are no longer available
- Terms with missing translations are now stuck with empty translations
- This is also written to disk. You can see the cache file is updated and all "[i2fb]" strings are removed. In practice, this does not matter because the language is never actually imported from these cache files (with these settings).
7. For completeness, UnloadLanguage is called again, though languages are already unloaded.
Note that the Editor behaves differently, as it clears the cache files from disk whenever you exit Play Mode. These means you can get some unintuitive behaviour if you play in Editor after playing Standalone (because there are cache files when usually they have been deleted), or by playing Standalone after playing in the Editor (because cache files will have been deleted, which puts you into the "first time" scenario above).
I totally understand that this might not be clear! The important bit is that the UnloadLanguage behaviour in step 5 above differs based on whether or not these cache files exist, which in turn affects how fallback translations are determined in step 6.
Last edit: 6 years 1 week ago by bkane. Reason: added I2Loc version
Please Log in or Create an account to join the conversation.
6 years 1 week ago #3368
by Frank
Are you Give I2L 5 stars!
Are you Please lets us know how to improve it!
Replied by Frank on topic Bug in UnloadLanguage + fallback strings
Hi,
THANKSSS for giving me so much detail!
I was able to reproduce the issue and will upload a fix as soon as possible.
Again, thanks a lot for all the information!!
Frank
THANKSSS for giving me so much detail!
I was able to reproduce the issue and will upload a fix as soon as possible.
Again, thanks a lot for all the information!!
Frank
Are you Give I2L 5 stars!
Are you Please lets us know how to improve it!
To get the betas as soon as they are ready,
check this out
Please Log in or Create an account to join the conversation.
5 years 11 months ago #3413
by Gray
Replied by Gray on topic Bug in UnloadLanguage + fallback strings
Great job documenting this! I just ran into the exact same issue (seems to be Windows only) and had temporarily disabled the unload. I came to the forum to report the issue.
Please Log in or Create an account to join the conversation.
Time to create page: 0.121 seconds