Difference between revisions of "Components"

From Forge Community Wiki
(Wording changes and updates)
(Update to 1.19)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''Text components''' (base interface <code>ITextComponent</code>) are forms of text used by Minecraft and Forge to concisely hold data relating to text. They form the basis of the chat system used in Minecraft. They are used for serializing and sending text data over network to players, displaying on clients, and styling for how the text appears with modifiers like bold and coloration.
+
'''Components''' (base interface <code>Component</code>) are forms of text used by Minecraft and Forge to concisely hold data relating to text. They form the basis of the chat system used in Minecraft. They are used for serializing and sending text data over network to players, displaying on clients, and styling for how the text appears with modifiers like bold and coloration.
  
There are two main types of text components: <code>StringTextComponent</code>s and <code>TranslationTextComponent</code>s. Both serve different purposes, although you should prefer the latter one for most general mod development. Both of these also extend from a base class of <code>TextComponent</code>, which has some important properties.
+
There are two main types of content a component can hold: <code>LiteralContents</code>s and <code>TranslatableContents</code>s. Both serve different purposes, although you should prefer the latter one for most general mod development.
  
== TextComponent ==
+
== MutableComponent ==
Text components at their most basic level hold a <code>Style</code> object and a list of "sibling" text components named <code>siblings</code>. In reality, these "siblings" are actually children of the main text component, and are treated as such when formatting with the <code>Style</code> object. A style can be applied to a text component by calling <code>withStyle</code> and <code>setStyle</code>. <code>withStyle</code> modifies the existing <code>Style</code> object with the given property, while <code>setStyle</code> replaces the current <code>Style</code> object. By default, text components use a style of <code>Style.EMPTY</code>, with an empty color representing white and empty properties meaning no special text formatting. To add a light blue color for example, one could simple call <code>theTextComponent.withStyle(TextFormatting.BLUE)</code>. This will merge the <code>BLUE</code> color with the existing <code>Style</code> object. When applying a parent text component's <code>Style</code> to its children text components, a non-null property of a child <code>Style</code> will take precedence over its parent <code>Style</code>. This means that if the color is set for both a child and parent text component, the child's color will be displayed. Otherwise, non-null properties from a parent text component's <code>Style</code> override properties from the child <code>Style</code> if they are null.
+
Components at their most basic level hold a <code>Style</code> object and a list of "sibling" components named <code>siblings</code>. In reality, these "siblings" are actually children of the main component, and are treated as such when formatting with the <code>Style</code> object. A style can be applied to a component by calling <code>withStyle</code> and <code>setStyle</code>. <code>withStyle</code> modifies the existing <code>Style</code> object with the given property, while <code>setStyle</code> replaces the current <code>Style</code> object. By default, components use a style of <code>Style.EMPTY</code>, with an empty color representing white and empty properties meaning no special chat formatting. To add a light blue color for example, one could simple call <code>theMutableComponent.withStyle(ChatFormatting.BLUE)</code>. This will merge the <code>BLUE</code> color with the existing <code>Style</code> object. When applying a parent component's <code>Style</code> to its children components, a non-null property of a child <code>Style</code> will take precedence over its parent <code>Style</code>. This means that if the color is set for both a child and parent component, the child's color will be displayed. Otherwise, non-null properties from a parent component's <code>Style</code> override properties from the child <code>Style</code> if they are null.
  
 
=== Appending siblings ===
 
=== Appending siblings ===
Siblings can be appended to text components similar to the plus (+) operator with Strings. Either <code>TextComponent#append(ITextComponent)</code> or <code>TextComponent#append(String)</code> can be called. The latter is an overload for the first function, and simply creates a new <code>StringTextComponent</code> with the provided String.
+
Siblings can be appended to components similar to the plus (+) operator with Strings via <code>MutableComponent#append(Component)</code>.
  
== StringTextComponent ==
+
== LiteralContents ==
String text components are the most basic form of text components. They are raw text components that contain a single String object. These are not preferred for general mod development as they cannot be translated into other languages. All properties of the base <code>TextComponent</code> apply to string text components.
+
Literal contents are the most basic form of component contents. They are raw contents that contain a single String object. These are not preferred for general mod development as they cannot be translated into other languages.
  
 
=== Creating ===
 
=== Creating ===
String text components are instantiated in the form <code>new StringTextComponent("Hello, world!")</code>. In practice, when sent to a player, this would simply be displayed as declared: <code>Hello, world!</code>.
+
Literal contents are instantiated in the form <code>new LiteralContents("Hello, world!")</code>. A component can be created with the contents using <code>Component#literal</code>. In practice, when sent to a player, this would simply be displayed as declared: <code>Hello, world!</code>.
  
 
=== Usage ===
 
=== Usage ===
String text components are most commonly used to create empty or space-filling text components, which can then link multiple text components together using <code>appendSibling</code>.
+
Literal contents are most commonly used to create empty or space-filling components, which can then be used to link multiple components together.
  
== TranslationTextComponent ==
+
== TranslatableContents ==
Translation text components are a more advanced form of text components that support String formatting and translation into multiple languages. Translation text components hold a '''translation key''', which is integral to translation into other languages. Translation keys are then mapped with a language file (commonly know as a lang file) to their appropriate entry for each translated language. It is important to note that the translation key is translated by the client, not the server. The server sends the translation key to the player, and the player's client converts the translation key into its fully expanded form when rendering depending on the player's selected language. If a player selects a specific language for which a translation key is not mapped, it will default to English.
+
Translatable contents are a more advanced form that support String formatting and translation into multiple languages. Translatable contents hold a '''translation key''', which is integral to translation into other languages. Translation keys are then mapped with a language file (commonly know as a lang file) to their appropriate entry for each translated language. It is important to note that the translation key is translated by the client, not the server. The server sends the translation key to the player, and the player's client converts the translation key into its fully expanded form when rendering depending on the player's selected language. If a player selects a specific language for which a translation key is not mapped, it will default to English.
  
 
=== Format modifiers ===
 
=== Format modifiers ===
Translation text components also support format modifiers like used in <code>String#format</code>. These format modifiers are declared by using the string <code>%s</code> when creating a translation entry for a given translation key. This format modifier will then be expanded and replaced with the provided object when rendered by the client. Any other format modifiers like <code>%d</code> or <code>%n</code> are ''not supported'' and will throw a formatting error. To get a normal percentage, a double percentage sign must be used (<code>%%</code>). A number can also be inserted, and it will be used as a 1-based index to select the argument. This is useful for choosing a specific argument out of order, or using the same argument twice. This looks like <code>%1$s</code>. The list of arguments to expand these format modifiers are passed to the constructor of the <code>TranslationTextComponent</code> using an Object varargs parameter, similar to <code>String#format</code>. The arguments passed in the constructor of a <code>TranslationTextComponent</code> can be either an Object or another <code>ITextComponent</code>. Any <code>ITextComponent</code>s will be expanded and have any declared <code>Style</code>s properties preserved in the final output. Any objects that are not an instance of <code>ITextComponent</code> will have <code>Object#toString</code> called during expansion.
+
Translatable contents also support format modifiers like used in <code>String#format</code>. These format modifiers are declared by using the string <code>%s</code> when creating a translation entry for a given translation key. This format modifier will then be expanded and replaced with the provided object when rendered by the client. Any other format modifiers like <code>%d</code> or <code>%n</code> are ''not supported'' and will throw a formatting error. To get a normal percentage, a double percentage sign must be used (<code>%%</code>). A number can also be inserted, and it will be used as a 1-based index to select the argument. This is useful for choosing a specific argument out of order, or using the same argument twice. This looks like <code>%1$s</code>. The list of arguments to expand these format modifiers are passed to the constructor of the <code>TranslatableContents</code> using an Object varargs parameter, similar to <code>String#format</code>. The arguments passed in the constructor of a <code>TranslatableContents</code> can be either an Object or another <code>Component</code>. Any <code>Component</code>s will be expanded and have any declared <code>Style</code>s properties preserved in the final output. Any objects that are not an instance of <code>Component</code> will have <code>Object#toString</code> called during expansion.
  
 
=== Creating ===
 
=== Creating ===
Translation text components are instantiated in the form <code>new TranslationTextComponent("your.translation_key.here", new StringTextComponent("thing1").withStyle(TextFormatting.RED), new StringTextComponent("thing1").withStyle(TextFormatting.BLUE))</code>. In your lang file, the entry would look something like: <syntaxhighlight lang="json">{
+
Translatable contents are instantiated in the form <code>new TranslatableContents("your.translation_key.here", new Component.literal("thing1").withStyle(ChatFormatting.RED), new Component.literal("thing2").withStyle(ChatFormatting.BLUE))</code>. A component can be created with the contents using <code>Component#translatable</code>. In your lang file, the entry would look something like:
 +
 
 +
<syntaxhighlight lang="json">
 +
{
 
     "your.translation_key.here": "I like using %1$s and %2$s!"
 
     "your.translation_key.here": "I like using %1$s and %2$s!"
}</syntaxhighlight>
+
}
In practice, when sent to a player, this would be displayed as <code>I like using thing1 and thing2!</code>, where <code>thing1</code> would be colored as red and <code>thing2</code> would be colored as blue. Normal <code>String</code>s can also be passed in, and they will inherit the <code>Style</code> object of the main text component. Note that any more values in the language file must be declared as comma-separated key-value pairs as required by the JSON specification, with the last key-value pair not ending with a comment.
+
</syntaxhighlight>
 +
 
 +
In practice, when sent to a player, this would be displayed as <code>I like using thing1 and thing2!</code>, where <code>thing1</code> would be colored as red and <code>thing2</code> would be colored as blue. Normal <code>String</code>s can also be passed in, and they will inherit the <code>Style</code> object of the main component. Note that any more values in the language file must be declared as comma-separated key-value pairs as required by the JSON specification, with the last key-value pair not ending with a comment.
  
 
=== Usage ===
 
=== Usage ===
Translation text components are used for sending anything visual to the player. Using them provides a benefit of format modifiers and the ability to be translated into different languages. This means that, given a translator, one could translate the English translation file (by default, <code>en_us.json</code>) into another language for a given mod. This system is also used by Minecraft itself and has been used to translate the game into hundreds of langauges. Translation keys are also required for declaring the names of items, blocks, and entities in the game.
+
Translatable contents are used for sending anything visual to the player. Using them provides a benefit of format modifiers and the ability to be translated into different languages. This means that, given a translator, one could translate the English translation file (by default, <code>en_us.json</code>) into another language for a given mod. This system is also used by Minecraft itself and has been used to translate the game into hundreds of languages. Translation keys are also required for declaring the names of items, blocks, and entities in the game.
  
  
 
[[Category:Translations]]
 
[[Category:Translations]]

Latest revision as of 16:16, 18 June 2022

Components (base interface Component) are forms of text used by Minecraft and Forge to concisely hold data relating to text. They form the basis of the chat system used in Minecraft. They are used for serializing and sending text data over network to players, displaying on clients, and styling for how the text appears with modifiers like bold and coloration.

There are two main types of content a component can hold: LiteralContentss and TranslatableContentss. Both serve different purposes, although you should prefer the latter one for most general mod development.

MutableComponent

Components at their most basic level hold a Style object and a list of "sibling" components named siblings. In reality, these "siblings" are actually children of the main component, and are treated as such when formatting with the Style object. A style can be applied to a component by calling withStyle and setStyle. withStyle modifies the existing Style object with the given property, while setStyle replaces the current Style object. By default, components use a style of Style.EMPTY, with an empty color representing white and empty properties meaning no special chat formatting. To add a light blue color for example, one could simple call theMutableComponent.withStyle(ChatFormatting.BLUE). This will merge the BLUE color with the existing Style object. When applying a parent component's Style to its children components, a non-null property of a child Style will take precedence over its parent Style. This means that if the color is set for both a child and parent component, the child's color will be displayed. Otherwise, non-null properties from a parent component's Style override properties from the child Style if they are null.

Appending siblings

Siblings can be appended to components similar to the plus (+) operator with Strings via MutableComponent#append(Component).

LiteralContents

Literal contents are the most basic form of component contents. They are raw contents that contain a single String object. These are not preferred for general mod development as they cannot be translated into other languages.

Creating

Literal contents are instantiated in the form new LiteralContents("Hello, world!"). A component can be created with the contents using Component#literal. In practice, when sent to a player, this would simply be displayed as declared: Hello, world!.

Usage

Literal contents are most commonly used to create empty or space-filling components, which can then be used to link multiple components together.

TranslatableContents

Translatable contents are a more advanced form that support String formatting and translation into multiple languages. Translatable contents hold a translation key, which is integral to translation into other languages. Translation keys are then mapped with a language file (commonly know as a lang file) to their appropriate entry for each translated language. It is important to note that the translation key is translated by the client, not the server. The server sends the translation key to the player, and the player's client converts the translation key into its fully expanded form when rendering depending on the player's selected language. If a player selects a specific language for which a translation key is not mapped, it will default to English.

Format modifiers

Translatable contents also support format modifiers like used in String#format. These format modifiers are declared by using the string %s when creating a translation entry for a given translation key. This format modifier will then be expanded and replaced with the provided object when rendered by the client. Any other format modifiers like %d or %n are not supported and will throw a formatting error. To get a normal percentage, a double percentage sign must be used (%%). A number can also be inserted, and it will be used as a 1-based index to select the argument. This is useful for choosing a specific argument out of order, or using the same argument twice. This looks like %1$s. The list of arguments to expand these format modifiers are passed to the constructor of the TranslatableContents using an Object varargs parameter, similar to String#format. The arguments passed in the constructor of a TranslatableContents can be either an Object or another Component. Any Components will be expanded and have any declared Styles properties preserved in the final output. Any objects that are not an instance of Component will have Object#toString called during expansion.

Creating

Translatable contents are instantiated in the form new TranslatableContents("your.translation_key.here", new Component.literal("thing1").withStyle(ChatFormatting.RED), new Component.literal("thing2").withStyle(ChatFormatting.BLUE)). A component can be created with the contents using Component#translatable. In your lang file, the entry would look something like:

{
    "your.translation_key.here": "I like using %1$s and %2$s!"
}

In practice, when sent to a player, this would be displayed as I like using thing1 and thing2!, where thing1 would be colored as red and thing2 would be colored as blue. Normal Strings can also be passed in, and they will inherit the Style object of the main component. Note that any more values in the language file must be declared as comma-separated key-value pairs as required by the JSON specification, with the last key-value pair not ending with a comment.

Usage

Translatable contents are used for sending anything visual to the player. Using them provides a benefit of format modifiers and the ability to be translated into different languages. This means that, given a translator, one could translate the English translation file (by default, en_us.json) into another language for a given mod. This system is also used by Minecraft itself and has been used to translate the game into hundreds of languages. Translation keys are also required for declaring the names of items, blocks, and entities in the game.