Host calls

Chat and text

On this page

Plain and formatted messages, titles, chat completions and capturing a player's next chat line.

Generated by tools/gen_api_docs.py; do not edit by hand. See host calls for how a call is made and how values are encoded. Each example shows the shape of a Wasm request with its required fields; the values in it are illustrative.

CallWhat it does
messageSends one person a line of chat.
capture_chatTakes player's next chat line for this plugin: it arrives as a bus call from rustmc:chat ({"op": "chat.captured", "player", "text"}) and goes nowhere else -- no player_chat hook or event, no log line, no broadcast -- so an answer typed in chat (a password, a name) is seen by the plugin that asked and by nobody else.
release_chatEnds this plugin's capture of a player's next line; whether one was open.
broadcastSends everybody one.
message_textSends one person a line of formatted chat: a text component as JSON (the game's own form: {"text": "Hi", "color": "gold", "extra": [...]}, or a bare string, or a list).
chat_completionsChanges the words a player's chat box offers to finish as they type (Paper's addCustomChatCompletions): an emoji's :shortcode:, a channel's name.
show_titleShows one person a title across the middle of their screen, and a subtitle under it: text components as message_text takes them.
broadcast_textSends everybody a line of formatted chat; how many it went to.

message

fn message(player: PlayerId, text: &str) -> ()

Sends one person a line of chat.

Wasm request

FieldTypeRequired
playerplayer id (integer)yes
textstringyes

Reply: {"ok": ...} holding the Rust return value (), encoded as in conventions.

{"call": "message", "player": 7, "text": "Hello"}

capture_chat

fn capture_chat(plugin: &str, player: PlayerId, wait_ms: u64, secret: bool) -> Result<Capture, String>

Takes player's next chat line for this plugin: it arrives as a bus call from rustmc:chat ({"op": "chat.captured", "player", "text"}) and goes nowhere else -- no player_chat hook or event, no log line, no broadcast -- so an answer typed in chat (a password, a name) is seen by the plugin that asked and by nobody else. One line, within wait_ms (at most fifteen minutes).

A line the plugin then cannot take (it was unloaded, or failed) is dropped, and the player told privately that their answer could not be delivered -- unless secret is false, when it is said in chat as if nobody had asked. secret is the safe default.

The answer says what came of it: Busy while another plugin waits for that player's line, Held once ten of their lines were captured in a row (until one reaches chat). An error only for a bad wait_ms.

Wasm request

FieldTypeRequired
playerplayer id (integer)yes
wait_mswhole number, 0 or moreyes
secrettrue or falseno

Shape and limits, as the router words its errors: "wait_ms should be a whole number of milliseconds".

Router notes: The capturing plugin is the manifest's name: a plugin takes lines for itself only. plugin is never sent by a Wasm guest: the server fills it in from the manifest name.

Reply: {"ok": ...} holding the Rust return value Result<Capture, String>, encoded as in conventions. An Err arrives as {"error": "..."}.

{"call": "capture_chat", "player": 7, "wait_ms": 60000}

release_chat

fn release_chat(plugin: &str, player: PlayerId) -> bool

Ends this plugin's capture of a player's next line; whether one was open.

Wasm request

FieldTypeRequired
playerplayer id (integer)yes

Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.

Reply: {"ok": ...} holding the Rust return value bool, encoded as in conventions.

{"call": "release_chat", "player": 7}

broadcast

fn broadcast(text: &str) -> ()

Sends everybody one.

Wasm request

FieldTypeRequired
textstringyes

Reply: {"ok": ...} holding the Rust return value (), encoded as in conventions.

{"call": "broadcast", "text": "Hello"}

message_text

fn message_text(player: PlayerId, component: &str, overlay: bool) -> Result<bool, String>

Sends one person a line of formatted chat: a text component as JSON (the game's own form: {"text": "Hi", "color": "gold", "extra": [...]}, or a bare string, or a list). overlay puts it above the hotbar instead of in the chat box. Answers whether it went: false for somebody who has gone; an error for JSON that is not a component or is over 32 KiB.

Wasm request

FieldTypeRequired
playerplayer id (integer)yes
componenttext component (JSON)yes
overlaytrue or falseno

Shape and limits, as the router words its errors: "component should be a text component".

Router notes: The component arrives as JSON and is handed on as its text: the host parses it once.

Reply: {"ok": ...} holding the Rust return value Result<bool, String>, encoded as in conventions. An Err arrives as {"error": "..."}.

{"call": "message_text", "player": 7, "component": {"text": "Hello", "color": "gold"}}

chat_completions

fn chat_completions(player: PlayerId, action: &str, words: &[String]) -> Result<bool, String>

Changes the words a player's chat box offers to finish as they type (Paper's addCustomChatCompletions): an emoji's :shortcode:, a channel's name. action is add, remove or set (replacing every word any plugin added). Player names are offered by the game itself. False for nobody there; an error for another action, more than 1000 words, or a word empty or longer than 256 characters.

Wasm request

FieldTypeRequired
playerplayer id (integer)yes
actionstringyes
wordslistyes

Shape and limits, as the router words its errors: "words should be a list of strings".

Reply: {"ok": ...} holding the Rust return value Result<bool, String>, encoded as in conventions. An Err arrives as {"error": "..."}.

{"call": "chat_completions", "player": 7, "action": "add", "words": ["alpha", "beta"]}

show_title

fn show_title(player: PlayerId, title: &str, subtitle: Option<&str>, fade_in: i32, stay: i32, fade_out: i32) -> Result<bool, String>

Shows one person a title across the middle of their screen, and a subtitle under it: text components as message_text takes them. fade_in, stay and fade_out are ticks, each 0 to 72000. Answers whether it went; an error for a bad component or timing.

Wasm request

FieldTypeRequired
fade_inwhole numberyes
staywhole numberyes
fade_outwhole numberyes
playerplayer id (integer)yes
titletext component (JSON)yes
subtitleJSON value, read into the Rust parameter subtitle: Option<&str>; see the doc commentno

Shape and limits, as the router words its errors: "title should be a text component"; "… is out of range".

Reply: {"ok": ...} holding the Rust return value Result<bool, String>, encoded as in conventions. An Err arrives as {"error": "..."}.

{"call": "show_title", "fade_in": 10, "stay": 70, "fade_out": 20, "player": 7, "title": {"text": "Title"}}

broadcast_text

fn broadcast_text(component: &str) -> Result<u32, String>

Sends everybody a line of formatted chat; how many it went to.

Wasm request

FieldTypeRequired
componenttext component (JSON)yes

Shape and limits, as the router words its errors: "component should be a text component".

Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.

{"call": "broadcast_text", "component": {"text": "Hello", "color": "gold"}}

From docs/api/reference/host-calls/text.md in the RustMC repository at bbd81209ad.