Detect language in Minecraft Vanilla

Is it possible to detect the player's Minecraft language in Singleplayer Minecraft (Vanilla)? If so, could you give me the command?


Solution 1:

That is not possible. What you can do is create language support in resource packs as you can see in maps like The Heist.

In the resource pack go to assets/minecraft/lang folder. Create files like EN_US.lang with content like:

language.name=English
language.region=US
language.code=en_US

container.dropper=Dopfer
container.furnace=New funace
container.enchant=Book stealer
container.crafting=

deathScreen.respawn=Restart!
deathScreen.title=Game Over

Hope it helped :)

Solution 2:

It is indeed possible to detect languages, but often you do not need to. The reason for both is the "translate" JSON tag.

Why you usually do not need to detect languages

If you just want to have entity names, item names and chat messages in the language of the player, then you can simply use the translate tag to automatically translate them to the target language:

/summon armor_stand ~ ~ ~ {CustomName:"{\"translate\":\"language.name\"}"}
/give @s stone{display:{Name:"{\"translate\":\"language.name\"}"}}
/tellraw @a [{"text":"Playing in "},{"translate":"language.name"}]

Results: An armour stand and a stone item whose names are "English" when playing in English UK, English US etc., "Deutsch" when playing in German and so on and a chat message that looks like "Playing in English" when playing in one of the English variants, "Playing in Deutsch" when playing in one of the German variants and so on.

You can overwrite strings and add new strings using a resource pack. More about that below.

How to actually detect languages

This is a bit more tricky and either requires a resource pack or could change at any point in time. You need a translatable string that is translated in all available languages, or at least all that are of interest to you. The problem is that for example, as I am writing this, there are 0 approved strings on Crowdin for the Tagalog translation (archive). So the only way to fully make sure that you can detect all available languages is by using a resource pack that adds a translatable string in all languages. (And when you do that, you can even add your own languages, if you want to.)

To detect a language, you need a dummy entity with a custom name. As far as I know, custom names are the only thing that can be set using JSON and read as regular strings (but there is also some black magic people have done that seems to work differently).

Firstly, set the translated string as the entity name:

/summon armor_stand 0 0 0 {CustomName:"{\"translate\":\"language.code\"}",Tags:["language"],Marker:1,NoGravity:1,Invisible:1}

Then do language checks:

/execute if entity @e[tag=language,name="en_uk"] run say English (Great Britain)
/execute if entity @e[tag=language,name="en_au"] run say English (Australia)
/execute if entity @e[tag=language,name="de_de"] run say German (Germany)

The language checks will always be the language that the player currently uses, not the one that was active when the entity was summoned. That means that you can prepare the dummy entity in your map and that you can apply language changes instantly.

Creating a resource pack for 100% reliable language checks

The problem with the method above: In theory someone could approve "en_UK" instead of "en_uk" as the language code of British English tomorrow. That is listed on Crowdin as having been suggested 7 years ago and it is the suggestion with the most upvotes, so I guess that it probably used to be the translation that was in the game for a while. "en_uk" was officially approved, but it's not unrealistic that it could change to e.g. "en_gb" at any time. I don't know how often translations are updated, but I know that it does not require a Minecraft update to do it, the launcher can download the latest translations indendent of the game itself. So the translation of your map could break at any point for any language.
To prevent this, you need a resource pack. Luckily they can be bundled with maps as well. To do this, put the "assets" folder, pack.mcmeta and pack.png (if it exists) into the top level of a ZIP file called "resources.zip". It does not work if the ZIP file contains a folder called "resources" at its top level and all other files inside that folder. Then simply put that ZIP file into the folder of the map.

The ZIP file's minimal structure:

pack.mcmeta
assets
└minecraft
 └lang
  ├en_gb.json
  ├en_au.json
  ├de_de.json
  └…

The minimal contents of pack.mcmeta:

{"pack":{"pack_format":5}}

The minimal contents of one of the language files:

{"a":"b"}

This would make the JSON {"translate":"a"} turn into the string b when interpreted. Ideally you would want to use something clearer, like a language code, but with a custom identifier, so that it doesn't overwrite the actual language code.

Creating custom languages

If you want your map to be available in more or other languages than Minecraft itself (or if you just want to translate Minecraft into other languages using a resource pack), then you can register custom languages in the pack.mcmeta file of your resource pack. This can for example be done like this:

{
 "pack":{
  "pack_format":5,
  "description":""
 },
 "language":{
  "test":{
   "name":"test language",
   "region":"test region"
  },
  "abc":{
   "name":"another language",
   "region":"another region"
  }
 }
}

You can use those languages by putting a corresponding file into assets/minecraft/lang, for example in this case test.json and abc.json. Note that "name" and "region" from pack.mcmeta are used for displaying the language in the languages menu. I don't know where "language.name" and "language.region" from the language's JSON files are supposed to be used by the game itself, but if you want them to be checkable with commands, you need to set them there as well.
These added languages always use "English (US)" as their bases, so all strings that you do not define in them will appear as in US English.

Multiplayer

In Multiplayer, each client sees translated JSON components in their own language, but commands detect the server-side language. When opening a Singleplayer game to LAN, this is simply the language of the host player's game. On dedicated servers this seems to always be "English (US)". My Debian system is set to "English (UK)", but the Minecraft server seems to ignore that. I do not know if there is a way to set a Minecraft server's language differently.

Sources

  • Article "Resource pack" on the Minecraft wiki: https://minecraft.gamepedia.com/Resource_pack (archive)
  • Article "Tutorials/Creating a resource pack" on the Minecraft wiki: https://minecraft.gamepedia.com/Tutorials/Creating_a_resource_pack#Adding_Languages (archive)
  • Original idea from this video, but heavily simplified and improved
  • Minecraft Vanilla resources unpacked and analysed with custom script
  • Tons of own experiments in the game