Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Werchat

Latest ReleaseLicenseDiscordGitHub Stars

Channel-based chat system for Hytale servers. Multiple channels, quick-chat routing, private messaging, nicknames, and moderation — all in one plugin.

Discord

Werchat

Features

Channel System — Multiple channels with custom colors, nicknames, distance-based and world-restricted delivery.

Quick Chat — Prefix symbols to route messages to any channel without switching. ! for Global, ~ for Trade.

Private Messaging/msg and /r with reply tracking, ignore lists, and offline detection.

Player Nicknames — Custom display names up to 20 characters with hex colors and two-color gradients.

Mention System@player highlighting with configurable color and bold formatting.

Clickable URLs — Chat and private messages automatically turn URLs into clickable links (configurable).

Moderation Tools — Per-channel ban, mute, moderators, word filter (censor/block modes), and chat cooldown.

In-Game Settings UI/ch, /ch settings, /ch list, and /ch help open a unified UI for profile, channels, and moderator tools.

Permission Integration — HyperPerms and LuckPerms prefix/suffix support with hex color codes.

PlaceholderAPI Integration — Supports external %...% placeholders in channel format text and includes a built-in %werchat_*% expansion.

Plugin API — Exposes a lightweight WerchatAPI for other plugins to query channels, manage membership/focus, and submit chat through Werchat's pipeline.

Message Colors — Independent message text colors and gradients, separate from nickname colors.

Persistent Storage — JSON-based data with dirty + debounced saves (20s) and a final flush on shutdown.

Quick Start

  1. Drop Werchat-1.11.3.jar in your mods/ folder
  2. Start your server — four default channels are created automatically
  3. Use /ch to open the settings UI (/ch list opens directly to Channels)
  4. Type !hello to quick-chat in Global or ~hello for Trade
/ch # Open Werchat settings UI
/ch list # Open Channels tab
/ch global # Switch to Global channel
/ch join trade # Join the Trade channel
/msg Steve Hey! # Send a private message
/ch playernick CoolName # Set your nickname

Default Channels

ChannelNickColorRangeAuto-JoinQuick-Chat Symbol
GlobalGlobalWhite (#ffffff)UnlimitedYes!
LocalLocalGray (#808080)100 blocksYes
TradeTradeGold (#ffd700)UnlimitedYes~
SupportSupportGreen (#00ff00)UnlimitedYes

Settings UI

  • /ch or /ch settings opens the Werchat settings UI.
  • Main tab includes focused-channel controls, nickname/color tools, and permission-filtered command help.
  • Channels tab includes join/leave/focus actions plus owner, description, and MOTD visibility.
  • Moderator channel management uses a dropdown selector so large channel counts stay usable.

Werchat Settings - Channels Tab

Commands

Player Commands

CommandAliasesDescription
/chOpen Werchat settings UI
/ch settingsOpen Werchat settings UI
/ch list/ch lOpen Channels tab in the settings UI
/ch join <channel> [password]/ch jJoin a channel
/ch leave <channel>Leave a channel
/ch <channel>Switch active channel
/ch who <channel>/ch wView channel members
/ch info <channel>View channel details
/ch create <name> [nick]Create a new channel
/ch playernick <name> [#color] [#gradient]/ch pnick, /ch nicknameSet your nickname
/ch msgcolor <#color> [#gradient]/ch chatcolorSet your message color
/ch help/ch ?Open Main tab help (permission-filtered)

Messaging Commands

CommandAliasesDescription
/msg <player> <message>/whisper, /w, /tell, /pmSend a private message
/r <message>/replyReply to last PM
/ignore <player>Toggle ignore on a player
/ignorelistList ignored players

Admin / Moderator Commands

CommandAliasesDescription
/ch color <channel> <#hex> [#hex]Set channel tag color (and optional message color)
/ch nick <channel> <nick>Set channel shortcut name
/ch rename <channel> <newname>Rename a channel
/ch password <channel> [password]/ch passSet or clear channel password
/ch distance <channel> <blocks>/ch rangeSet range (0 = unlimited)
/ch world <channel> add|remove <world>Restrict channel to worlds
/ch mod <channel> <player>/ch moderatorAdd a channel moderator
/ch unmod <channel> <player>Remove a channel moderator
/ch ban <channel> <player>Ban a player from a channel
/ch unban <channel> <player>Unban a player
/ch mute <channel> <player>Mute a player in a channel
/ch unmute <channel> <player>Unmute a player
/ch remove <channel>/ch delete, /ch delDelete a channel
/ch reloadReload Werchat config and channel data from disk

Channel moderators can use admin commands on their own channels without needing global permission nodes.

If /ch create <name> is used without a nick, Werchat auto-generates a short nick from the first character and disambiguates collisions:

  • Example: 12312345 -> 1, 1234903425 -> 1-2, 1 -> 1-3.
All Permissions
PermissionDescription
werchat.*All Werchat permissions (wildcard)
werchat.listList channels
werchat.joinJoin channels
werchat.leaveLeave channels
werchat.createCreate channels
werchat.whoView channel members
werchat.infoView channel info
werchat.switchSwitch active channel
werchat.colorSet channel colors
werchat.nickSet channel nick
werchat.passwordSet channel password
werchat.renameRename channels
werchat.removeDelete channels
werchat.modManage channel moderators
werchat.distanceSet channel range
werchat.banBan/unban from channels
werchat.muteMute/unmute in channels
werchat.worldSet world restrictions
werchat.reloadReload Werchat config/channel data
werchat.msgSend private messages
werchat.ignoreIgnore players
werchat.quickchatUse quick-chat symbols
werchat.playernickSet own nickname
werchat.playernick.othersSet other players' nicknames
werchat.nickcolorSet nickname color/gradient
werchat.msgcolorSet own message color
werchat.msgcolor.othersSet other players' message color
werchat.cooldown.bypassBypass chat cooldown

Players with werchat.* or * also bypass cooldowns and the word filter.

Per-channel permission nodes:

  • werchat.channel.<channel>.join
  • werchat.channel.<channel>.speak
  • werchat.channel.<channel>.read (primary receive/read node)

These nodes are enforced in normal /ch + chat flow only when channelPermissions.enforce is enabled.

Configuration

Config file: mods/com.werchat_Werchat/config.json

View full config
{
"defaultChannelName": "Global",
"autoJoinDefault": true,
"showJoinLeaveMessages": true,
"allowPrivateMessages": true,
"channelPermissions": {
"enforce": false
},
"banMessage": "You have been banned from {channel}",
"muteMessage": "You have been muted in {channel}",
"wordFilter": {
"enabled": false,
"mode": "censor",
"replacement": "***",
"notifyPlayer": true,
"warningMessage": "Your message contained inappropriate language.",
"words": ["..."]
},
"cooldown": {
"enabled": false,
"seconds": 3,
"message": "Please wait {seconds}s before sending another message.",
"bypassPermission": "werchat.cooldown.bypass"
},
"mentions": {
"enabled": true,
"color": "#FFFF55"
},
"clickableUrls": {
"enabled": true
},
"ignoreChatCancellations": false
}
KeyDefaultDescription
defaultChannelName"Global"Default channel players are placed in
autoJoinDefaulttrueAuto-join default channel on connect
showJoinLeaveMessagestrueBroadcast join/leave messages to channels
allowPrivateMessagestrueWhether /msg is enabled
channelPermissions.enforcefalseEnforce per-channel join/speak/read nodes in normal /ch + chat flow
banMessage"You have been banned from {channel}"Message shown to banned players
muteMessage"You have been muted in {channel}"Message shown to muted players
wordFilter.enabledfalseEnable the word filter
wordFilter.mode"censor"censor replaces bad words, block rejects the message
wordFilter.replacement"***"Replacement string in censor mode
wordFilter.notifyPlayertrueWarn the player when filtered
wordFilter.warningMessage"Your message contained..."Warning message text
wordFilter.words[]Words to filter (case-insensitive); empty by default
cooldown.enabledfalseEnable chat cooldown
cooldown.seconds3Seconds between messages
cooldown.message"Please wait {seconds}s..."Cooldown message
cooldown.bypassPermission"werchat.cooldown.bypass"Permission to bypass cooldown
mentions.enabledtrueEnable @mention highlighting
mentions.color"#FFFF55"Hex color for mention highlights
clickableUrls.enabledtrueConvert detected URLs in chat/PM text into clickable links
ignoreChatCancellationsfalseProcess chat even if cancelled by other plugins

When channelPermissions.enforce is enabled:

  • join checks run in /ch join and /ch <channel> auto-join.
  • speak checks run before sending messages.
  • read checks run for sender selection and per-recipient delivery.
  • Password checks still apply; permission nodes never bypass channel passwords.
Channel Format Placeholders

Custom channel message formats support these placeholders:

PlaceholderDescription
{name}Full channel name
{nick}Channel nick/abbreviation
{color}Channel color code
{sender}Player display name
{msg}Message content
{prefix}Player's permission prefix (HyperPerms/LuckPerms)
{suffix}Player's permission suffix (HyperPerms/LuckPerms)

Default format: {nick} {sender}: {msg}

Format literals also support PlaceholderAPI placeholders when PlaceholderAPI is installed. {prefix} / {suffix} resolve directly from HyperPerms/LuckPerms when those plugins are present, even without PlaceholderAPI placeholders.

Werchat also registers a built-in PlaceholderAPI expansion with identifier werchat.

Top-level Werchat placeholders:

PlaceholderDescription
%werchat_channels_total%Total number of channels
%werchat_channels%Comma-separated channel names
%werchat_default_channel%Default channel name
%werchat_selected_channel%Focused channel name for the player (recommended)
%werchat_selected_channel_<key>%Focused channel field/value by key (preferred keyed form)
%werchat_channel%Focused channel name for the player (legacy alias)
%werchat_channel_<selector>%Specific channel by selector (returns channel name)
%werchat_channel_<selector>_<key>%Specific channel field/value by selector + key (primary keyed form)
%werchat_channel_<selector>__<key>%Edge-case keyed syntax for selectors with underscore ambiguity
%werchat_ignored_players_total%Number of ignored players
%werchat_ignored_players%Comma-separated ignored player names
%werchat_known_name%Real account username
%werchat_display_colour%Player display color
%werchat_display_color%Player display color (US spelling alias)
%werchat_msg_color%Player message color
%werchat_msg_gradient%Player message gradient as #START,#END (blank when no gradient)
%werchat_msg_gradient_end%Player message gradient end color
%werchat_nick_color%Player nickname color
%werchat_nick_gradient_end%Player nickname gradient end color
%werchat_nick%Custom nickname only (blank if none set)
%werchat_display_name%Final chat name (nickname if set, else username)

Name placeholder semantics:

  • known_name: always the real account name.
  • nick: only the custom nickname value, can be blank.
  • display_name: what Werchat renders in chat.

Channel-scoped Werchat placeholder syntax:

Preferred keyed forms:

%werchat_selected_channel_<key>%

%werchat_channel_<selector>_<key>%

Braced selector forms (recommended for underscore channel names):

%werchat_channel_{<selector>}%

%werchat_channel_{<selector>}_<key>%

Direct channel selector alias:

%werchat_channel_<selector>% (returns that channel's name)

Edge-case keyed form (use only when selector/key underscore ambiguity appears):

%werchat_channel_<selector>__<key>%

<selector> values:

  • Exact channel name or nick.
  • Optional {} wrapper is supported for explicit selectors (example: {trade_german}).
  • Channel names with underscores are supported (example: trade_name).
  • Legacy active alias (active by default) is still supported for compatibility.

Key separator note:

  • _ (single underscore) is the primary keyed separator.
  • __ (double underscore) is the backup separator for ambiguous channel names (example: trade_name).
  • Example explicit form: %werchat_channel_{trade_german}_member_count%.

<key> values:

KeyDescription
nameChannel's canonical name (what admins create/rename)
nickChannel's short label/alias
colorhexChannel tag color as hex (#RRGGBB)
formatRaw channel format template string
colorChannel tag color as hex (#RRGGBB)
effective_msg_colorhexFinal message text color hex (message color override or tag color fallback)
join_permissionPermission node string associated with joining this channel (werchat.channel.<name>.join)
read_permissionPermission node string associated with reading/receiving this channel (werchat.channel.<name>.read)
msg_color_hexExplicit message text color hex override (#RRGGBB), blank when unset
msg_colorExplicit message text color hex (#RRGGBB), blank when unset
quickchatsymbolQuick-chat trigger symbol (for example !), blank when unset
speak_permissionPermission node string associated with speaking in this channel (werchat.channel.<name>.speak)
worlds_countNumber of configured world restrictions
worldsWorlds shown as text (All worlds or a comma-separated list)
distanceChannel chat range in blocks (0 means global/unlimited)
member_countCurrent number of channel members
member_namesComma-separated member names (online username, fallback known name, then short UUID)
moderator_countCurrent number of channel moderators
moderator_namesComma-separated moderator names (online username, fallback known name, then short UUID)
muted_countCurrent number of muted members
muted_namesComma-separated muted member names (online username, fallback known name, then short UUID)
ownerChannel owner UUID
owner_nameBest-known owner name (online username fallback to stored known name)
is_autojointrue if this channel auto-joins players on connect
is_mutedtrue if the requesting player context is muted in this channel
is_bannedtrue if the requesting player context is banned from this channel
is_membertrue if the requesting player context is a member of this channel
is_moderatortrue if the requesting player context is a moderator of this channel
is_verbosetrue if channel verbose mode is enabled
is_defaulttrue if this is the server default channel
is_focusabletrue if players are allowed to focus/select this channel
is_globaltrue if channel range is global (distance <= 0)
is_localtrue if channel range is local (distance > 0)
has_passwordtrue if a password is set on this channel
has_msg_colortrue if explicit message color override is set
has_worldstrue if world restrictions are configured
has_quickchatsymboltrue if a quick-chat symbol is configured
Plugin API

Access Werchat's integration API:

WerchatAPIapi = WerchatPlugin.api();
if (api != null) {
WerchatOperationOptionsopts = WerchatOperationOptions.enforcePermissions();
WerchatActionResultjoin = api.joinChannel(playerId, "trade", null, opts);
if (join.isSuccess()) {
api.setFocusedChannel(playerId, "trade", opts);
api.submitPlayerChat(playerId, "Selling iron!", opts);
}
}

API notes:

  • submitPlayerChat(...) is the primary API method for submitting player chat.
  • WerchatActionResult and WerchatMembershipResult expose explicit status enums instead of booleans.
  • Channel lookups can now be explicit: use getChannelExact(...), joinChannelExact(...), setFocusedChannelExact(...), etc. for deterministic integrations, or default/fuzzy methods for command-like behavior.
  • api.getApiVersion(), api.getCapabilities(), and api.hasCapability(...) let integrations gate behavior safely.
  • Hooks are available through registerHook(...) / unregisterHook(...) for pre/post API action handling.
Building from Source

Requirements: Java 21+, Gradle 8.12+ (wrapper included)

./gradlew buildRelease
# Output: build/libs/Werchat-1.11.3.jar (built for latest release channel)

Build variants:

./gradlew buildRelease # latest release channel
./gradlew buildPreRelease # latest pre-release channel
./gradlew build # defaults to release channel

The plugin manifest.jsonServerVersion is injected automatically at build time from Hytale Maven metadata.
If you need a manual override for testing, set an explicit version:

./gradlew build -Phytale_server_version=2026.02.18-f3b8fff95

Links


Part of the HyperSystems suite: HyperPerms | HyperHomes | HyperFactions | Werchat

About

A fully featured chat plugin including a chat channel system for Hytale servers. Organize player communication with customizable channels, private messaging, and moderation tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages