Chat

From wiki.vg
Revision as of 00:40, 5 January 2024 by LassiPulkkinen (talk | contribs) (→‎Social Interactions (blocking): Mention that even overlay messages are searched for blocked player names.)
Jump to navigation Jump to search

Minecraft supports two-way chat communication via the Player Chat Message packet, which support a variety of formatting options. Note that this system isn't exclusive to the Chat Message packet - it's used in several other places (including written books, death messages, window titles, and the like).

Heads up!

Currently out of date. 1.20.3+ encodes the JSON Chat into NBT in most cases when sent over the network (indicated via the Chat and Json Chat data types). How its converted in both directions needs to be documented.

Current system (JSON Chat)

Chat data is sent in JSON. For most situations, the JSON is strictly parsed, but lenient JSON parsing is used for the Disconnect packet and for written book text.

Inheritance

Each component can have multiple siblings. Each sibling component inherits properties from the style of its parent, using those styles if they are not defined in the sibling's own style.

For example, in this component:

{
    "text": "foo",
    "bold": true,
    "extra": [
        {
            "text": "bar"
        },
        {
            "text": "baz",
            "bold": false
        },
        {
            "text": "qux",
            "bold": true
        }
    ]
}

The text "foo", "bar", and "qux" are all rendered as bold while "baz" is not.

Schema

Each situation where a component can appear may be either a JSON object (the most common choice), an array, or a JSON primitive (which is converted to a String).

JSON primitives can be used for components, in which case they are implicitly converted into a String component. Note that it is invalid to have a JSON primitive as the root object, so it is not valid to merely send the text in quotes. This shorthand is useful for sibling lists, though.

It is also legal to put a JSON array where a component would go, so long as the array is not empty. The first component in the array is the parent of all of the following components. This can produce unusual behavior with style inheritance, but it is still useful shorthand.

The most common type of component is a JSON object; the format is as follows:

Shared between all components

All component types have certain fields that represent the style. All of these fields may be skipped, in which case the parent's style will be inherited.

bold
Boolean - if true, the component is emboldened.
italic
Boolean - if true, the component is italicized.
underlined
Boolean - if true, the component is underlined.
strikethrough
Boolean - if true, the component is struck out.
obfuscated
Boolean - if true, the component randomly switches between characters of the same width.
font
String - You can choose between minecraft:uniform (Unicode font), minecraft:alt (Enchanting table font) or minecraft:default (the default font, which switches based on the user's texture pack). This option is only valid on 1.16+, otherwise the property is ignored.
color
String - contains the color for the component. Should be one of the normal colors, but can also be a format code (however, the fields relating to styles should be used instead for that purpose) or any valid web color(since 1.16.x). If not present (or set to reset), then the default color for the text will be used, which varies by the situation (in some cases, it is white; in others, it is black; in still others, it is a shade of gray that isn't normally used on text).
insertion
String - contains text to insert. Only used for messages in chat. When shift is held, clicking the component inserts the given text into the chat box at the cursor (potentially replacing selected text). Has no effect on other locations at this time.
clickEvent
JSON object - Defines an event that occurs when this component is clicked. Contains the fields action and value, both strings.
action may be one of the following:
open_url
Opens the given URL in the default web browser. Ignored if the player has opted to disable links in chat; may open a GUI prompting the user if the setting for that is enabled. The link's protocol must be set and must be http or https, for security reasons.
open_file
Cannot be used within JSON chat. Opens a link to any protocol, but cannot be used in JSON chat for security reasons. Only exists to internally implement links for screenshots.
run_command
Runs the given command. Not required to be a command - clicking this only causes the client to send the given content as a chat message, so if not prefixed with /, they will say the given text instead. If used in a book GUI, the GUI is closed after clicking.
twitch_user_info
No longer supported; cannot be used within JSON chat. Only usable in 1.8 and below; twitch support was removed in 1.9. Additionally, this is only used internally by the client. On click, opens a twitch user info GUI screen. Value should be the twitch user name.
suggest_command
Only usable for messages in chat. Replaces the content of the chat box with the given text - usually a command, but it is not required to be a command (commands should be prefixed with /).
change_page
Only usable within written books. Changes the page of the book to the given page, starting at 1. For instance, "value":"1" switches the book to the first page. If the page is less than one or beyond the number of pages in the book, the event is ignored.
copy_to_clipboard
Copies the given text to the client's clipboard when clicked.
hoverEvent
JSON object - Defines an event that occurs when this component hovered over. Contains the fields action (a string) and contents (dependent on action).

Warning.png The content field was introduced in Minecraft 1.16, replacing the old value field, which is still supported by new versions for compatibility. value functioned similarly to content, but was always interpreted as a chat component, with show_item and show_entity data represented as sNBT (e.g. "value":"{id:35,Damage:5,Count:2,tag:{display:{Name:Testing}}}").

action may be one of the following:
show_text
Displays a tooltip with arbitrary text. contents can either be a string directly ("contents":"la") or a full component ("contents":{"text":"la","color":"red"}).
show_item
Displays a tooltip describing an item. contents contains the following fields:
id
The textual identifier of the item's type. If unrecognized, defaults to minecraft:air.
count
The number of items in the item stack. If omitted, defaults to 1.
tag
The item's NBT information as an sNBT string (as would be used in /give) (if present).
show_entity
Displays a tooltip describing an entity. Shown only if Advanced tooltips (F3+H) is enabled. contents contains the following fields:
type
The textual identifier of the entity's type. If unrecognized, defaults to minecraft:pig.
id
The entity's UUID (with dashes). Does not need to correspond to an existing entity; only for display.
name
The entity's custom name (if present).
show_achievement
No longer supported. Since 1.12, this no longer exists; advancements instead simply use show_text. The ID of an achievement or statistic to display. Example: "value":"achievement.openInventory".
extra
An array of sibling components. If present, cannot be empty.

Beyond that, there are additional properties. Attempt to parse as each of the following in the order they are described:

String component

A String component contains only text. If the JSON contains a text key, then the component is a String component. The only content of this component is its text, with no additional processing.

Translation component

Huh.png The following information needs to be added to this page:
Is using this with an invalid key intended or deprecated? Also, what exactly happens on invalid formats?

Translates text into the current language. If the JSON contains a translate key, then the component is a translation component.

Translation supports %s, %n$s (where n is an index) and %% format tokens. %% is just an escaped percent symbol. %s marks text to replace using content from the optional with tag. with is an array of components. %n$s acts like %s but instead will use the text component in with that is at the index of n.

It should be noted that when the key is not known by a language file, it will result in the translation key being the value of the text. For Example, soundCategory.hostile exists and will result in "Hostile Creatures" whereas soundCategory.angry (Which does not exist) will result in "soundCategory.angry".

Warning.png Prior to 1.19.1 the narrator was hardcoded to replace the translation key chat.type.text with chat.type.text.narrate. This mechanism has been superseded by chat types, and is no longer present in new versions.

Keybind component

Displays the client's current keybind for the specified key. If the component contains a keybind key, then it is a keybind component. The value is named after the keys in options.txt (for instance, for key_key.forward in options.txt, key.forward would be used in the component and W would be displayed). For keys that are not known, the value provided should be displayed instead (for instance key.invalid would remain as key.invalid).

Score component

Displays a score. If the JSON contains a score key, then the component is a score component.

The score JSON object contains data about the objective.

When being sent to the client, it must contain name, objective, and value keys. name is a player username or entity UUID (if it is a player, it is a username); objective is the name of the objective; value is the resolved value of that objective.

When being sent to the server, value is not used. name can be an entity selector (that selects one entity), or alternatively * which matches the sending player.

Selector component

Displays the results of an entity selector. If the component contains a selector key, then it is a selector component.

Warning.png This component is meant for client-to-server interactions (such as commands), and should not be sent directly to the client.

If received by the client, it won't be resolved, and will always be displayed as the selection pattern.

The server resolves the list selector into a list of entities, each with an appropriate hover event (and click event if it happens to be a player).

Entries in the list are separated by a comma by default, but can be overriden with any component if a separator is specified.

NBT component

Displays the results of a NBT query. If the component contains a nbt key, then it is a NBT component.

Warning.png This component is meant for client-to-server interactions (such as commands), and should not be sent directly to the client.

If received by the client, it won't be resolved, and will always be displayed as empty text.

The server constructs a list using the data found at the nbt path, for each entry of a given source. This source varies, and is defined by the presence of one of the three following fields:

  • block, where the data comes from the block entity at the given position;
  • entity, where the data comes from the entities resulted from the given entity selector;
  • storage, where the data comes from the internal storage defined by the given Identifier.

Entries in the list are separated by a comma by default, but can be overriden with any component if a separator is specified.

Furthermore, if the boolean interpret is set to true, the server will attempt to resolve each of the data as its own component, before appending them with the separator.

Examples

Here are some examples from the Notchian server for how chat formatting can be used.

TODO - additional examples

Standard chat message

The normal chat message uses a translation component along with some styling.

Warning.png Since 1.19.1 the Notchian client uses the chat type mechanism, meaning chat messages are no longer sent directly like shown in this example.

{"translate":"chat.type.text","with":[{"text":"Herobrine","clickEvent":{"action":"suggest_command","value":"/msg Herobrine "},"hoverEvent":{"action":"show_entity","value":"{id:f84c6a79-0a4e-45e0-879b-cd49ebd4c4e2,name:Herobrine}"},"insertion":"Herobrine"},{"text":"I don't exist"}]}

The chat.type.text translation key becomes <%s> %s, which is then filled in with the player's name and the actual message. Note that the player's name has a click event (which inserts text to message the player), a hover event (which shows the entity ID; also note that type is missing), and an insertion (for the player's name).

Old system

Control Sequences

The client treats certain two-character sequences specially. The first character must be:

  • § (U+00A7) for Minecraft
  • & for Minecraft Classic

The following character indicates a certain color or formatting to apply to the proceeding text.

In Minecraft Classic, the Notchian client expects that an escape code in a chat message will be followed by at least one character, and will otherwise crash with a StringIndexOutOfBoundsException. The server must sanitize outbound messages by removing any control characters at the end.

Colors

These correspond very roughly to the colors available in ANSI terminals.

e.g.: This is white, but §4this is dark red

Hex digit to color mapping
  1. REDIRECT Text formatting/ColorSample
Sample Code Common Name Name Foreground Color Background Color
R G B Hex R G B Hex
0 Black black 0 0 0 #000000 0 0 0 #000000
1 Dark blue dark_blue 0 0 170 #0000aa 0 0 42 #00002a
2 Dark green dark_green 0 170 0 #00aa00 0 42 0 #002a00
3 Dark cyan dark_aqua 0 170 170 #00aaaa 0 42 42 #002a2a
4 Dark red dark_red 170 0 0 #aa0000 42 0 0 #2a0000
5 Purple dark_purple 170 0 170 #aa00aa 42 0 42 #2a002a
6 Gold gold 255 170 0 #ffaa00 42 42 0 #2a2a00
7 Gray gray 170 170 170 #aaaaaa 42 42 42 #2a2a2a
8 Dark gray dark_gray 85 85 85 #555555 21 21 21 #151515
9 Blue blue 85 85 255 #5555ff 21 21 63 #15153f
a Bright green green 85 255 85 #55ff55 21 63 21 #153f15
b Cyan aqua 85 255 255 #55ffff 21 63 63 #153f3f
c Red red 255 85 85 #ff5555 63 21 21 #3f1515
d Pink light_purple 255 85 255 #ff55ff 63 21 63 #3f153f
e Yellow yellow 255 255 85 #ffff55 63 63 21 #3f3f15
f White white 255 255 255 #ffffff 63 63 63 #3f3f3f

Styles

Like the color codes above, style escape codes are created by combining § (U+00A7) with one of the following characters. Style codes can be combined (except for "r") to enable multiple effects at once. The "k" random style code is used for the "§kFUNKY LOL" message in /title/splashes.txt inside minecraft.jar.

Sample Code Style Name
Random chat.gif k Random obfuscated
Bold chat.png l Bold bold
Strikethrough chat.png m Strikethrough strikethrough
Underlined chat.png n Underlined underline
Italic chat.png o Italic italic
Plain chat.png r Plain White reset

Processing chat

Client chat mode

The client may use the Chat Mode field of the Client Information packet to indicate that it only wants to receive some types of chat messages.

It is the server's responsibility to not send packets if the client has the given type disabled. However, it is the client's responsibility to not send incorrect chat packets.

Here's a matrix comparing what packets the server should send to a clients based on their chat settings:

Clientbound packet Client setting Usage
Full Commands only Hidden
Player Chat Message Player-initiated chat messages, including the commands /say, /me, /msg, /tell, /w and /teammsg.
Disguised Chat Message Messages sent by non-players using the commands /say, /me, /msg, /tell, /w and /teammsg.
System Chat Message Feedback from running a command, such as "Your game mode has been updated to creative."
System Chat Message (overlay) Game state information that is displayed above the hot bar, such as "You may not rest now, the bed is too far away".

Here's a matrix comparing what the client may send based on its chat setting:

Serverbound packet Client setting
Full Commands only Hidden
Chat Message [note 1]
Chat Command

If the client attempts to send a chat message and the server rejects it, the Notchian server will send that client a System Chat Message (non-overlay) with a red chat.disabled.options translation component (which becomes "Chat disabled in client options.").

Social Interactions (blocking)

1.16 added a social interactions screen that lets players block chat from other players. Blocking takes place clientside by detecting whether a message is from a blocked player.

Player Chat Message packets are blocked based on the included sender UUID.

Disguised Chat Message packets are never blocked.

System Chat Message packets (regardless of the Overlay field!) are blocked based on the first occurrence of <playername> anywhere in the message, including split across multiple chat components, where playername may be any text, including the empty string or whitespace. If playername is the name of a blocked player (matched case-sensitively), the message is blocked. This only occurs if Hide Matched Names is enabled in Chat Settings (the default).

Font

Minecraft has two fonts types that can be encountered normally: Ascii (ascii.png) and Unicode (unicode_page_XX.png). The ascii font will fall back upon unicode characters if they are not provided (see below). However, use of the Unicode font can be forced for all characters in the language menu.

There is no glyph for the space character. However, the space character has a width of 4.

Additionally, Minecraft has a Standard Galactic Alphabet font (ascii_sga.png). This cannot be used in chat, but works much the same as the normal Ascii font in terms of width. The SGA font only supports lowercase and uppercase letters (the rest of the glyphs are blank), and has the same indexing as the normal ascii font.

The Minecraft client calculates the widths of the default font when the texture is loaded, whilst the sizes of the unicode type are provided in glyph_sizes.bin. Each byte in glyph_sizes.bin contains the start and end position of each character, the top nibble (0xF0) is the start position and the bottom nibble (0x0F) is the end position (relative to the character's position in the font sheet). Example: https://gist.github.com/TkTech/dff9bbe54c9a074612e1

The Ascii font supports these characters, with the given indexes in ascii.png:

Codepoint Char index x y width
\u00c0 À 0 0 0 6
\u00c1 Á 1 1 0 6
\u00c2 Â 2 2 0 6
\u00c8 È 3 3 0 6
\u00ca Ê 4 4 0 6
\u00cb Ë 5 5 0 6
\u00cd Í 6 6 0 4
\u00d3 Ó 7 7 0 6
\u00d4 Ô 8 8 0 6
\u00d5 Õ 9 9 0 6
\u00da Ú 10 10 0 6
\u00df ß 11 11 0 6
\u00e3 ã 12 12 0 6
\u00f5 õ 13 13 0 6
\u011f ğ 14 14 0 6
\u0130 İ 15 15 0 4
\u0131 ı 16 0 1 4
\u0152 Œ 17 1 1 6
\u0153 œ 18 2 1 7
\u015e Ş 19 3 1 6
\u015f ş 20 4 1 6
\u0174 Ŵ 21 5 1 6
\u0175 ŵ 22 6 1 6
\u017e ž 23 7 1 6
\u0207 ȇ 24 8 1 6
\u0000 [note 2] 25 9 1 -
\u0000 [note 2] 26 10 1 -
\u0000 [note 2] 27 11 1 -
\u0000 [note 2] 28 12 1 -
\u0000 [note 2] 29 13 1 -
\u0000 [note 2] 30 14 1 -
\u0000 [note 2] 31 15 1 -
\u0020 32 0 2 4[note 3]
\u0021 ! 33 1 2 2
\u0022 " 34 2 2 5
\u0023 # 35 3 2 6
\u0024 $ 36 4 2 6
\u0025 % 37 5 2 6
\u0026 & 38 6 2 6
\u0027 ' 39 7 2 3
\u0028 ( 40 8 2 5
\u0029 ) 41 9 2 5
\u002a * 42 10 2 5
\u002b + 43 11 2 6
\u002c , 44 12 2 2
\u002d - 45 13 2 6
\u002e . 46 14 2 2
\u002f / 47 15 2 6
\u0030 0 48 0 3 6
\u0031 1 49 1 3 6
\u0032 2 50 2 3 6
\u0033 3 51 3 3 6
\u0034 4 52 4 3 6
\u0035 5 53 5 3 6
\u0036 6 54 6 3 6
\u0037 7 55 7 3 6
\u0038 8 56 8 3 6
\u0039 9 57 9 3 6
\u003a : 58 10 3 2
\u003b ; 59 11 3 2
\u003c < 60 12 3 5
\u003d = 61 13 3 6
\u003e > 62 14 3 5
\u003f ? 63 15 3 6
\u0040 @ 64 0 4 7
\u0041 A 65 1 4 6
\u0042 B 66 2 4 6
\u0043 C 67 3 4 6
\u0044 D 68 4 4 6
\u0045 E 69 5 4 6
\u0046 F 70 6 4 6
\u0047 G 71 7 4 6
\u0048 H 72 8 4 6
\u0049 I 73 9 4 4
\u004a J 74 10 4 6
\u004b K 75 11 4 6
\u004c L 76 12 4 6
\u004d M 77 13 4 6
\u004e N 78 14 4 6
\u004f O 79 15 4 6
\u0050 P 80 0 5 6
\u0051 Q 81 1 5 6
\u0052 R 82 2 5 6
\u0053 S 83 3 5 6
\u0054 T 84 4 5 6
\u0055 U 85 5 5 6
\u0056 V 86 6 5 6
\u0057 W 87 7 5 6
\u0058 X 88 8 5 6
\u0059 Y 89 9 5 6
\u005a Z 90 10 5 6
\u005b [ 91 11 5 4
\u005c \ 92 12 5 6
\u005d ] 93 13 5 4
\u005e ^ 94 14 5 6
\u005f _ 95 15 5 6
\u0060 ` 96 0 6 3
\u0061 a 97 1 6 6
\u0062 b 98 2 6 6
\u0063 c 99 3 6 6
\u0064 d 100 4 6 6
\u0065 e 101 5 6 6
\u0066 f 102 6 6 5
\u0067 g 103 7 6 6
\u0068 h 104 8 6 6
\u0069 i 105 9 6 2
\u006a j 106 10 6 6
\u006b k 107 11 6 5
\u006c l 108 12 6 3
\u006d m 109 13 6 6
\u006e n 110 14 6 6
\u006f o 111 15 6 6
\u0070 p 112 0 7 6
\u0071 q 113 1 7 6
\u0072 r 114 2 7 6
\u0073 s 115 3 7 6
\u0074 t 116 4 7 4
\u0075 u 117 5 7 6
\u0076 v 118 6 7 6
\u0077 w 119 7 7 6
\u0078 x 120 8 7 6
\u0079 y 121 9 7 6
\u007a z 122 10 7 6
\u007b { 123 11 7 5
\u007c | 124 12 7 2
\u007d } 125 13 7 5
\u007e ~ 126 14 7 7
\u0000 [note 2] 127 15 7 -
\u00c7 Ç 128 0 8 6
\u00fc ü 129 1 8 6
\u00e9 é 130 2 8 6
\u00e2 â 131 3 8 6
\u00e4 ä 132 4 8 6
\u00e0 à 133 5 8 6
\u00e5 å 134 6 8 6
\u00e7 ç 135 7 8 6
\u00ea ê 136 8 8 6
\u00eb ë 137 9 8 6
\u00e8 è 138 10 8 6
\u00ef ï 139 11 8 4
\u00ee î 140 12 8 6
\u00ec ì 141 13 8 3
\u00c4 Ä 142 14 8 6
\u00c5 Å 143 15 8 6
\u00c9 É 144 0 9 6
\u00e6 æ 145 1 9 6
\u00c6 Æ 146 2 9 6
\u00f4 ô 147 3 9 6
\u00f6 ö 148 4 9 6
\u00f2 ò 149 5 9 6
\u00fb û 150 6 9 6
\u00f9 ù 151 7 9 6
\u00ff ÿ 152 8 9 6
\u00d6 Ö 153 9 9 6
\u00dc Ü 154 10 9 6
\u00f8 ø 155 11 9 6
\u00a3 £ 156 12 9 6
\u00d8 Ø 157 13 9 6
\u00d7 × 158 14 9 4
\u0192 ƒ 159 15 9 6
\u00e1 á 160 0 10 6
\u00ed í 161 1 10 3
\u00f3 ó 162 2 10 6
\u00fa ú 163 3 10 6
\u00f1 ñ 164 4 10 6
\u00d1 Ñ 165 5 10 6
\u00aa ª 166 6 10 6
\u00ba º 167 7 10 6
\u00bf ¿ 168 8 10 6
\u00ae ® 169 9 10 7
\u00ac ¬ 170 10 10 6
\u00bd ½ 171 11 10 6
\u00bc ¼ 172 12 10 6
\u00a1 ¡ 173 13 10 2
\u00ab « 174 14 10 6
\u00bb » 175 15 10 6
\u2591 176 0 11 8
\u2592 177 1 11 9
\u2593 178 2 11 9
\u2502 179 3 11 6
\u2524 180 4 11 6
\u2561 181 5 11 6
\u2562 182 6 11 8
\u2556 183 7 11 8
\u2555 184 8 11 6
\u2563 185 9 11 8
\u2551 186 10 11 8
\u2557 187 11 11 8
\u255d 188 12 11 8
\u255c 189 13 11 8
\u255b 190 14 11 6
\u2510 191 15 11 6
\u2514 192 0 12 9
\u2534 193 1 12 9
\u252c 194 2 12 9
\u251c 195 3 12 9
\u2500 196 4 12 9
\u253c 197 5 12 9
\u255e 198 6 12 9
\u255f 199 7 12 9
\u255a 200 8 12 9
\u2554 201 9 12 9
\u2569 202 10 12 9
\u2566 203 11 12 9
\u2560 204 12 12 9
\u2550 205 13 12 9
\u256c 206 14 12 9
\u2567 207 15 12 9
\u2568 208 0 13 9
\u2564 209 1 13 9
\u2565 210 2 13 9
\u2559 211 3 13 9
\u2558 212 4 13 9
\u2552 213 5 13 9
\u2553 214 6 13 9
\u256b 215 7 13 9
\u256a 216 8 13 9
\u2518 217 9 13 6
\u250c 218 10 13 9
\u2588 219 11 13 9
\u2584 220 12 13 9
\u258c 221 13 13 5
\u2590 222 14 13 9
\u2580 223 15 13 9
\u03b1 α 224 0 14 8
\u03b2 β 225 1 14 7
\u0393 Γ 226 2 14 7
\u03c0 π 227 3 14 8
\u03a3 Σ 228 4 14 7
\u03c3 σ 229 5 14 8
\u03bc μ 230 6 14 8
\u03c4 τ 231 7 14 8
\u03a6 Φ 232 8 14 7
\u0398 Θ 233 9 14 8
\u03a9 Ω 234 10 14 8
\u03b4 δ 235 11 14 7
\u221e 236 12 14 9
\u2205 237 13 14 9
\u2208 238 14 14 6
\u2229 239 15 14 7
\u2261 240 0 15 7
\u00b1 ± 241 1 15 7
\u2265 242 2 15 7
\u2264 243 3 15 7
\u2320 244 4 15 9
\u2321 245 5 15 6
\u00f7 ÷ 246 6 15 7
\u2248 247 7 15 8
\u00b0 ° 248 8 15 7
\u2219 249 9 15 6
\u00b7 · 250 10 15 6
\u221a 251 11 15 9
\u207f 252 12 15 7
\u00b2 ² 253 13 15 6
\u25a0 254 14 15 7
\u0000 [note 2] 255 15 15 -
Huh.png The following information needs to be added to this page:
Clearer documentation on how rendering works (for instance, shadows)

Notes

  1. This behavior varies. The Notchian server previously rejected chat messages, but now allows them to go through (sending them to all players, but they're invisible on the sender's side). CraftBukkit and derivatives continue to reject this. See MC-116824 for more information.
  2. 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 This code point isn't supported, and may be replaced with another character in a future version. \u0000 should be directly skipped instead of being rendered with this code point.
  3. The space character is mapped to an index within ascii.png, but the width is hardcoded to 4 and the character at that position is not rendered.