diff --git a/.config/spelling_wordlist.txt b/.config/spelling_wordlist.txt index d6a7bae..3805c68 100644 --- a/.config/spelling_wordlist.txt +++ b/.config/spelling_wordlist.txt @@ -64,3 +64,7 @@ aro philly bigender demigender +Minestom +nullable +Javadocs +codebase diff --git a/source/conf.py b/source/conf.py index 8869d00..324c5f2 100644 --- a/source/conf.py +++ b/source/conf.py @@ -22,7 +22,7 @@ from pathlib import Path project = 'Adventure' -copyright = '2020-2025 KyoriPowered' +copyright = '2020-2025 KyoriPowered. Not official Minecraft software. Not approved by or associated with Mojang or Microsoft.' author = 'KyoriPowered' # The short X.Y versions diff --git a/source/contributing.rst b/source/contributing.rst index 876bd3a..442dc29 100644 --- a/source/contributing.rst +++ b/source/contributing.rst @@ -42,7 +42,7 @@ These instructions assume you are working from a terminal, either on Windows or 5. Open a browser to ``https://localhost:8000`` to view the just-built site. Pages will auto-refresh when changes are made. -Any text editor will work for editing the documentation, but we've had the best experience with Visual Studio Code or (neo)vim, each of which have mature reST plugins. +Any text editor will work for editing the documentation, but we've had the best experience with Visual Studio Code or :spelling:ignore:`(neo)vim`, each of which have mature reST plugins. A typical development environment has a text editor and web browser side-by-side, with the web browser viewing the locally served test site. Once you've written changes, they can be submitted for inclusion in the docs with a GitHub Pull Request. diff --git a/source/index.rst b/source/index.rst index 5fe9bd9..37e97eb 100644 --- a/source/index.rst +++ b/source/index.rst @@ -39,6 +39,7 @@ There are many community-supported libraries that extend the capabilities of Adv tablist resource-pack minimessage/index + localization platform/index diff --git a/source/localization.rst b/source/localization.rst new file mode 100644 index 0000000..ef55cad --- /dev/null +++ b/source/localization.rst @@ -0,0 +1,125 @@ +.. _localization: + +Localization +============ + +Adventure provides a way to utilize Minecraft's built-in localization system for client-side translations as well as an additional Adventure-specific system for translating text. + +Using Minecraft's localization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To send text to a player that will be translated in the language they have selected in their client settings, use a translatable component. +For example, :java:`Component.translatable("block.minecraft.diamond_block")` will render as "Block of Diamond" (or translated to another language) when viewed by the client. +Some translation keys have arguments which are inserted into the translated content. +For example, :java:`Component.translatable("block.minecraft.player_head.named", Component.text("Mark"))` will render as "Mark's Head". +Translatable components can have styling, hover/click events and children components just like any other component type. + +Resource pack language files +---------------------------- + +You can provide translation files in a resource pack in order to change existing translations or add new ones. +For a guide on how to do that, see the `Minecraft Wiki `_. + +Using Adventure's localization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Adventure also provides a way to handle localization in Adventure itself. +This can be useful in environments where you do not have access to resource packs, or wish to do translations yourself, without relying on Minecraft's translation system. + +Any component that is sent to a client is ran through the ``GlobalTranslator`` using the locale of the client. +This means that if you wish to have automatic translation of components using your own translation data, you can add a ``Translator`` to the ``GlobalTranslator``. +You can either provide your own implementation of ``Translator`` or use one of the implementations that Adventure provides. + +Once you have a ``Translator`` instance, you can register it to the ``GlobalTranslator`` using :java:`GlobalTranslator.translator().addSource(myTranslator)`. +This will then make it available for automatic translation across the platform. + +.. warning:: + + Some implementations may not use the ``GlobalTranslator`` in every area, or at all. + For example, Paper does not use it for items, and Minestom does not use it unless specifically enabled. + Please consult the documentation for your platform for any limitations. + +Using a custom ``Translator`` +----------------------------- + +A ``Translator`` is a simple interface that provides two ways of translating content. + +The first ``translate`` method provides the translation key and locale as an argument and expects a nullable ``MessageFormat`` in return. +This system is comparable to Minecraft's built-in localization system, using the standard Java `message format `_ for arguments. + +If the first ``translate`` method returns ``null``, the second method which provides the translatable component and locale as an argument can be used. +This method allows for much richer customization of the translation process as you can return an entire component. +This means you can, for example, customize the color and styling of the translated component, rather than relying solely on strings for the message format system. + +.. warning:: + + If you are overriding the component ``translate`` method, you should be careful not to unintentionally lose the children of the translatable component. + See the Javadocs for the translate method for a code example of how to avoid this common error. + +Below is an example of how one might implement a custom ``Translator``. + +.. code:: java + + public class MyTranslator implements Translator { + + @Override + public @NotNull Key name() { + // Every translator has a name which is used to identify this specific translator instance. + return Key.key("mynamespace:mykey"); + } + + @Override + public @Nullable MessageFormat translate(final @NotNull String key, final @NotNull Locale locale) { + // You could retrieve a string from a properties file, a config file, or some other system. + // An an example, we will hard-code a check for a specific key here. + if (key.equals("mytranslation.key") && locale == Locale.US) { + return new MessageFormat("Hello %s!", locale); + } else { + // If you only want to use component translation, you can override this method and always return `null`. + return null; + } + } + + @Override + public @Nullable Component translate(@NotNull TranslatableComponent component, @NotNull Locale locale) { + // As above, we will hardcode a check here, but you should be reading this from elsewhere. + if (key.equals("mytranslation.colorful") && locale == Locale.US) { + return Component.text("Hello, ", NamedTextColor.GREEN) + .append(component.arguments().get(0).color(NamedTextColor.RED)) + .append(component.children()); // Always make sure to copy the children over! + } else { + return null; + } + } + } + +Using a ``TranslationStore`` +------------------------------- + +A ``TranslationStore`` is a store of translations. +It provides a simpler way creating a ``Translator`` without having to implement the logic for determining and storing translations yourself. +You can create a translation store and then add or remove translations at will, even after registering it to the global translator. + +Adventure provides two translation stores, one for message format translating and one for component translating. +An example of how to use a translation store is below. + +.. code:: java + + // As above, every translator needs an identifying name! + // Could also use TranslationStore#component(Key) to work with components instead. + final TranslationStore myStore = TranslationStore.messageFormat(Key.key("mynamespace:mykey")); + + // You can add translations one-by-one, or in bulk. Consult the Javadocs for a full list of methods. + myStore.register("mytranslation.key", Locale.US, new MessageFormat("Hello %s!", Locale.US)); + + // You can then register this to the global translator so the translations are available there! + GlobalTranslator.translator().addSource(myStore); + +There are additional methods on the message format translation store to bulk register from `resource bundles `_. +You may also want to use Adventure's ``UTF8ResourceBundleControl`` utility class to create your bundle. + +Using MiniMessage for translations +---------------------------------- + +Adventure also provides a translator that can use MiniMessage strings, with automatic support for placeholders and arguments. +For more information, see :ref:`minimessage-translator`. diff --git a/source/minimessage/format.rst b/source/minimessage/format.rst index 03a5115..d36f07f 100644 --- a/source/minimessage/format.rst +++ b/source/minimessage/format.rst @@ -89,7 +89,7 @@ Color the shadow of the next parts Tag * :mm:`` - * :mm:`` as an alias to disable the shadow (equalivent to :mm:``) + * :mm:`` as an alias to disable the shadow (equivalent to :mm:``) Arguments * ``_colorNameOrHex_``, a named color or hex color string with the format ``#RRGGBB`` or ``#RRGGBBAA`` * ``[alpha_as_float]``, a float value between 0 and 1, representing the alpha value of the shadow. Optional, defaults to 0.25. Has no effect if an alpha value is already provided in the hex color string. diff --git a/source/minimessage/index.rst b/source/minimessage/index.rst index b09a395..6f2d58c 100644 --- a/source/minimessage/index.rst +++ b/source/minimessage/index.rst @@ -16,3 +16,4 @@ If you're looking to write messages with MiniMessage, take a look at the :ref:`m format api dynamic-replacements + translator diff --git a/source/minimessage/translator.rst b/source/minimessage/translator.rst new file mode 100644 index 0000000..e7f553a --- /dev/null +++ b/source/minimessage/translator.rst @@ -0,0 +1,63 @@ +.. _minimessage-translator: + +MiniMessage Translator +====================== + +.. note:: + + For more information about both Minecraft and Adventure's localization systems, see :ref:`localization`. + +MiniMessage provides a ``Translator`` implementation that allows you to use MiniMessage as translation strings. +It also provides automatic support for argument placeholders, letting you use simple translatable components throughout your codebase. + +Creating a MiniMessage translator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To start, create an implementation of the ``MiniMessageTranslator`` and register it to the ``GlobalTranslator``. +This can be done using :java:`GlobalTranslator.translator().addSource(myMiniMessageTranslator)`. +For an example of how to create your own ``MiniMessageTranslator``, see the below code block. + +.. code:: java + + public class MyMiniMessageTranslator extends MiniMessageTranslator() { + + public MyMiniMessageTranslator() { + // By default, the standard MiniMessage instance will be used. + // You can specify a custom one in the super constructor. + super(MiniMessage.miniMessage()); + } + + @Override + public @Nullable String getMiniMessageString(final @NotNull String key, final @NotNull Locale locale) { + // Creating a custom MiniMessage translator is as simple as overriding this one method. + // All you need to do is return a MiniMessage string for the provided key and locale. + // In this example we will hardcode this, but you could pull it from a resource bundle, a properties file, a config file or something else entirely. + if (key.equals("mykey") && locale == Locale.US) { + return "Hello, ! Today is ." + } else { + // Returning null "ignores" this translation. + return null; + } + } + } + +MiniMessage translation store +----------------------------- + +In order to make managing a ``MiniMessageTranslator`` easier, we also provide a ``TranslationStore`` implementation using MiniMessage strings. +For documentation on how to use translation stores, see :ref:`localization`. + +Note that the ``MiniMessageTranslationStore`` contains the same methods as the message format translation store for populating a translation store using resource bundles. + +Using a MiniMessage translator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The MiniMessage translator will automatically turn translatable component arguments into a custom tag. +This tag will be :mm:`` or :mm:`` where ``index`` is the zero indexed position of the argument. +For example, this component :java:`Component.translatable(key, Component.text("Kezz"))` with the MiniMessage string :mm:`Hello, !` will produce "Hello, Kezz!". + +You can also use the `Argument` class to create named tags for ease of use. +For example, this component :java:`Component.translatable(key, Argument.component("name", Component.text("Kezz"))` will produce the string "Hello, Kezz!" when used with either :mm:`Hello, !` or :mm:`Hello, !`. + +Finally, you can also add entirely custom tags or tag resolvers to the deserialization by using the rest of the methods on ``Argument``. +For a full list, please see the Javadocs for the ``Argument`` class. diff --git a/source/platform/native.rst b/source/platform/native.rst index 6c8f83d..778dc30 100644 --- a/source/platform/native.rst +++ b/source/platform/native.rst @@ -4,24 +4,24 @@ Native Support ============== -Native platforms integrate Adventure directly with their platform's provided API, and bundle Adventure automatically. -This allows them to more tightly integrate Adventure with the rest of the game, and avoids users having to handle distributing +Native platforms integrate Adventure directly with their platform's provided API, and bundle Adventure automatically. +This allows them to more tightly integrate Adventure with the rest of the game, and avoids users having to handle distributing Adventure and some platform adapter themselves. The following software provide native support for Adventure. -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ -| Platform | Minimum Version | Additional Notes | -+==============================+======================================+===============================================================================================================+ -| Sponge | Sponge 8 (1.16.5) | | -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ -| Velocity | 1.1.0 build 158 | For more information, see the | -| | | `Velocity Docs `_. | -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ -| Paper | 1.16.5 build 473 | | -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ -| :spelling:ignore:`Minestom` | Build 7494725 | For more information, see the | -| | | `Minestom Wiki `_. | -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ -| Fabric | ``adventure-platform-fabric`` 5.3.0 | This is not strictly native, but injected interfaces provide a near-native experience | -+------------------------------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Platform | Minimum Version | Additional Notes | ++===========+======================================+===============================================================================================================+ +| Sponge | Sponge 8 (1.16.5) | | ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Velocity | 1.1.0 build 158 | For more information, see the | +| | | `Velocity Docs `_. | ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Paper | 1.16.5 build 473 | | ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Minestom | Build 7494725 | For more information, see the | +| | | `Minestom Wiki `_. | ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Fabric | ``adventure-platform-fabric`` 5.3.0 | This is not strictly native, but injected interfaces provide a near-native experience | ++-----------+--------------------------------------+---------------------------------------------------------------------------------------------------------------+