OoT-Randomizer icon indicating copy to clipboard operation
OoT-Randomizer copied to clipboard

RE: The setting to change the Language of the game to Any language

Open JackTriton opened this issue 6 months ago • 29 comments

Hi, it's been a long time This PR is redo of all of the functions I made almost 5 years ago

Description

With this PR, you can play OOTR with different languages or event texts / custom texts as well


Addition

Files

  • language (folder): Consists every language you can play with
    Also, you can add another language file just by drag and drop the file with same structure
    For how to create and what file is included, checkout language / README.md
  • Language.py: allows to manage language files (json, bin, ia4)

Additional Control Codes for wide characters

  • All of the additional control codes are placed the code + 0x8700 (for example, silver rupee count is placed 0xF0 + 0x8700 = 0x87F0)
    For the character to use, check out Messages.py

Text alignment

  • You can change the alignment of the text to Left, Center and Right

How to Change the language?

You can change the language by changing Main Rules >> Language >> Language Selection


Tips for language creation

If you want to add language with characters not included in vanilla game (for example Spanish has ñ), do the same thing as other images: decompile the original game, replace some files with new one and recompile / get diff with get_diff.py


Notes

Currently, besides English which is already implemented from beginning, it allows you to play with Japanese as well
Why Japanese? well, it's because Japanese is the other language that NTSC rom has and one of language that uses wide characters instead and also because I'm Japanese

Just because I didn't implemented other languages such as German, French or Chinese (which is PAL and iQue version has), that doesn't mean you can't play with those languages or other languages that only got the translated version by using mod / patch or even that never got the version

Not only that, you can create version for events, competition or even speedruns as well (like shortening all of the texts, and speed up everything)

Screen shots

Setting View

Title for Japanese

Title for English

JackTriton avatar Aug 05 '25 05:08 JackTriton

Most of the system reworked, deleted .DS_Store, add some descriptions to the property_build.py and changed some of the values to have clearer infos

JackTriton avatar Aug 05 '25 22:08 JackTriton

Sorry there was some typos in japanese/property.json

JackTriton avatar Aug 07 '25 05:08 JackTriton

Got different errors when trying to generate in English and Japanese.

English:

<Dungeon.Dungeon object at 0x000001EEE96AD480>
Traceback (most recent call last):
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\OoTRandomizer.py", line 57, in start
    main(settings)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 57, in main
    patch_and_output(settings, spoiler, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 375, in patch_and_output
    patch_cosmetics_log = prepare_rom(spoiler, world, rom, settings, rng_state, restore_rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 214, in prepare_rom
    patch_rom(spoiler, world, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Patches.py", line 1849, in patch_rom
    "dungeon_reward": world.language.hintTable[dungeon][1],
KeyError: <Dungeon.Dungeon object at 0x000001EEE96AD480>

Seems to be because the dungeon name has a control code in it. Also, pretty sure the the should be dropped and it should just be Deku Tree... image image

Japanese:

from_bytes() missing required argument 'byteorder' (pos 2)
Traceback (most recent call last):
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\OoTRandomizer.py", line 57, in start
    main(settings)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 57, in main
    patch_and_output(settings, spoiler, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 375, in patch_and_output
    patch_cosmetics_log = prepare_rom(spoiler, world, rom, settings, rng_state, restore_rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 214, in prepare_rom
    patch_rom(spoiler, world, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Patches.py", line 1176, in patch_rom
    update_message_by_id(messages, 0x305C, lang.format_from_id("PATCH_TEXTS.claim"), lang)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Messages.py", line 748, in update_message_by_id
    text = line_wrap(text, lang.base, align=lang.lang_property["align_text"])
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\TextBox.py", line 51, in line_wrap
    text_codes = Messages.parse_control_codes(text, lang)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Messages.py", line 345, in parse_control_codes
    text_bytes = encode_text_string(text) if lang else encode_text_string_jp(text)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Messages.py", line 295, in encode_text_string_jp
    result.append(int.from_bytes(h.encode("cp932")))
TypeError: from_bytes() missing required argument 'byteorder' (pos 2)

Adding byteorder="big" to the function call fixed it, but I'm not actually sure why that was necessary when the function definition already sets it to big by default? result.append(int.from_bytes(h.encode("cp932"), byteorder="big"))

def from_bytes(
            cls,
            bytes: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer,
            byteorder: Literal["little", "big"] = "big",
            *,
            signed: bool = False,
        )

@flagrama any ideas here?

Anyway, fixing that issue ran into the same issue English did with the dungeon name. image

cjohnson57 avatar Aug 10 '25 00:08 cjohnson57

Got different errors when trying to generate in English and Japanese.

English:

<Dungeon.Dungeon object at 0x000001EEE96AD480>
Traceback (most recent call last):
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\OoTRandomizer.py", line 57, in start
    main(settings)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 57, in main
    patch_and_output(settings, spoiler, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 375, in patch_and_output
    patch_cosmetics_log = prepare_rom(spoiler, world, rom, settings, rng_state, restore_rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Main.py", line 214, in prepare_rom
    patch_rom(spoiler, world, rom)
  File "C:\Users\Caleb\Repos\OoT-Randomizer-Tests\Patches.py", line 1849, in patch_rom
    "dungeon_reward": world.language.hintTable[dungeon][1],
KeyError: <Dungeon.Dungeon object at 0x000001EEE96AD480>

LangDev here, this is probably because of the given value is dungeon instead of dungeon_reward

For the requested changes, moving the language_selection in SettingsList.py to below logic_rules would be great?

JackTriton avatar Aug 10 '25 00:08 JackTriton

Thanks for your quick fixes on my first two messages! Can confirm they're resolved. I could launch the ROM and talk to NPCs and read hints in both English and Japanese.

cjohnson57 avatar Aug 10 '25 00:08 cjohnson57

Thanks for your quick fixes on my first two messages! Can confirm they're resolved. I could launch the ROM and talk to NPCs and read hints in both English and Japanese.

Regarding the last request, I'll edit them right now!

JackTriton avatar Aug 10 '25 00:08 JackTriton

One question, what exactly is the purpose of the property_build.py file? It seems to mainly contain the English messages that are now formatted in the English folder's property.json. Is it to generate the property.json?

cjohnson57 avatar Aug 10 '25 00:08 cjohnson57

Adding byteorder="big" to the function call fixed it, but I'm not actually sure why that was necessary when the function definition already sets it to big by default? result.append(int.from_bytes(h.encode("cp932"), byteorder="big"))

FYI, the default value is just a change made in python 3.11. If you are using 3.11 or newer, this error won't appear. If you are using anything older this error comes up. If you are using 3.11 or newer but you have your dev environment set up to ensure everything works as far back as 3.8 it may be doing something additional to cause that error to show up.

flagrama avatar Aug 10 '25 00:08 flagrama

Interesting, ty for the info!

cjohnson57 avatar Aug 10 '25 00:08 cjohnson57

One question, what exactly is the purpose of the property_build.py file? It seems to mainly contain the English messages that are now formatted in the English folder's property.json. Is it to generate the property.json?

property_build.py creates property.json for the language The default value would be the ones on English for compare / know what string to use

Also, the PLANE_TEXTS would be the ones for other texts to implement in game when the language is not on NTSC or any kind of variety

JackTriton avatar Aug 10 '25 00:08 JackTriton

Gotcha. Should that be "plain" texts?

cjohnson57 avatar Aug 10 '25 01:08 cjohnson57

Gotcha. Should that be "plain" texts?

Oh, sorry yes PLAIN_TEXTS

JackTriton avatar Aug 10 '25 01:08 JackTriton

@cjohnson57 Thanks for the detailed reviews!

JackTriton avatar Aug 10 '25 02:08 JackTriton

Add UnitTest that checks language file / properties

Below this is template for the errors

If the language file misses property.json {lang_name}: property.json is not included

If some properties are missing / wrong in property.json {lang_name}: some properties are wrong in property.json

If some bin files are not included in the bin_patch.json {lang_name}: some non-wanted bin files are included

JackTriton avatar Aug 15 '25 09:08 JackTriton

Unless the conflicts revolve with in-game messages or custom texts, all conflicts will be resolved after merging

JackTriton avatar Aug 22 '25 03:08 JackTriton

Conflicts have to be fixed before merging, that's just how git (and other version control software) works. Do you mean "after it is reviewed"?

flagrama avatar Aug 22 '25 14:08 flagrama

Conflicts in generated files are fine to leave unresolved, they will be fixed by the maintainer who merges the PR.

fenhl avatar Aug 22 '25 14:08 fenhl

Conflicts in generated files are fine to leave unresolved, they will be fixed by the maintainer who merges the PR.

Oh, yeah, I'm on the app so don't know how to look at the actual conflicts. If that's all it is, ignore me.

flagrama avatar Aug 22 '25 14:08 flagrama

This update is to confirm what's fixed and got worse with the current code

JackTriton avatar Aug 28 '25 08:08 JackTriton

This project is not abandoned: currently waiting for change requests / pull requests on the ReLanguage branch

JackTriton avatar Oct 10 '25 02:10 JackTriton

Hi @JackTriton, now that we've released 9.0 I'm making this PR a priority. Unfortunately some merge conflicts popped up so you will have to take care of those, hopefully they're not too bad.

@fenhl When you get back in a few days, can you re-check the PR to see if all your issues have been resolved?

cjohnson57 avatar Dec 31 '25 17:12 cjohnson57

Also, apologies, I just realized that we never added the "waiting for release" tag which is where this PR was for the last couple months.

cjohnson57 avatar Dec 31 '25 17:12 cjohnson57

This is before the conflict reviews

I hope there's no conflicts revolving around additional control codes / ASM files

JackTriton avatar Jan 01 '26 02:01 JackTriton

@cjohnson57 @fenhl In order to resolve all the conflicts, I have to make this branch up to date

Currently working on the text part and I think it'll be renewed in next 24 hours

JackTriton avatar Jan 01 '26 06:01 JackTriton

Reopen this with newer commits Sorry for the extra request (#2506)

JackTriton avatar Jan 01 '26 16:01 JackTriton

@cjohnson57 @fenhl I think it's ready for the review

JackTriton avatar Jan 01 '26 17:01 JackTriton

Thank you. Once fenhl gets back and does their review, I'll also go through it again, then we'll try to do some testing and then merge.

cjohnson57 avatar Jan 01 '26 21:01 cjohnson57

Currently, the branch conflicts revolving around ASM and generated data The ASM part doesn't conflict with this branch so I think Pull request + rebuild would resolve the issue

JackTriton avatar Jan 02 '26 22:01 JackTriton

Currently, the branch conflicts revolving around ASM and generated data The ASM part doesn't conflict with this branch so I think Pull request + rebuild would resolve the issue

Yes, those are nothing to worry about.

cjohnson57 avatar Jan 02 '26 22:01 cjohnson57

FYI, fenhl is preparing a PR to your branch for some hint region cleanup. In the meantime I will try to do a test seed with JP full randotext next week to see if anything breaks.

cjohnson57 avatar Jan 11 '26 04:01 cjohnson57