Chat¶
Chat is a system rather than a format string, because a server that grows past about thirty players needs somewhere to put the noise.
Channels¶
Five out of the box. Each is a conversation with its own rules: who may speak, who hears it, how far it carries, and what a line looks like.
| Channel | Shortcut | Reaches |
|---|---|---|
| Global | ! |
Everybody |
| Local | = |
120 blocks |
| Trade | $ |
Everybody |
| Support | ? |
Everybody |
| Staff | # |
Staff only, unfiltered |
/channel picks where you are talking. A shortcut sends one line somewhere
else without switching, which is how people actually use staff chat.
Local chat tells you when nobody heard you, rather than letting you talk to an empty room and wonder why nobody answered.
Filters¶
Everything below is off for anyone with emberessentials.chat.bypass, and each
has its own bypass node.
Profanity. Matching normalises first, so f-u-c-k and fu(k are the same
word as the plain spelling. Doubled letters collapse and lookalike characters
are folded, which catches the people who are trying rather than only the people
who are not. A hit masks the word and keeps the sentence.
Advertising. URLs, bare domains and IP addresses are stopped unless the domain is on the allow list.
Caps. A long message that is mostly capitals is lowercased rather than blocked. Shouting is enthusiasm, not an offence.
Spam and repeats. A minimum gap between messages, and the same line twice in a row is refused.
Emoji¶
Thirty shortcodes, such as :shrug:, :heart: and :tableflip:, plus a few
bare substitutions like <3 that only fire when they stand alone, so a
coordinate is left alone. /emojis shows every one a player can use and puts
the code in their chat box rather than sending it, so the menu teaches the
shortcode instead of replacing it.
Set per-emoji-permission: true to gate them individually, which is how you
sell the good ones.
Chat tags¶
Thirteen tags a player chooses and wears in front of their name. A tag is not a rank prefix: a prefix says what somebody is and staff set it; a tag says something about them and they pick it from what they have unlocked.
Unlocking is a permission, so LuckPerms does the work:
/tag opens the wardrobe. Locked tags are still shown with what unlocks them,
because a tag nobody can see is a tag nobody wants.
In chat¶
Say somebody by name and they hear a chime. Type [item] and what you are
holding appears, hoverable. Hover a name to offer to message them.
Colour codes in chat are a permission (emberessentials.chat.colour), and a
message from somebody without it is inserted as literal text, so nothing a
player types can ever become a tag.
Moderation¶
| Command | What it does |
|---|---|
/chatlock |
Stops everybody but staff talking |
/chatslow <seconds> |
A minimum gap between messages |
/wipechat |
Clears every screen; staff keep theirs |
/chatfilter |
What is on, and reloads it |
Bots¶
Answering the questions your staff answer forty times a day.
"how do i claim land", "where is spawn", "is there a discord" - a busy server
answers these hundreds of times a week, and staff who answer them all day stop
answering anything else. An instant reply is worth more than the same text
buried in /rules, because it arrives at the moment somebody actually wanted
it.
chat-bots:
enabled: true
bots:
discord:
match: contains
triggers: ["discord", "is there a disc"]
cooldown-seconds: 60
reply:
- "<#5865f2><bold>Discord</bold> <dark_gray>ยป <white>discord.gg/yourserver"
match is contains, exact, starts or regex.
Two settings keep this from being the most annoying thing on the server, and both default to the quiet option:
cooldown-secondsis per bot, not per player. Three people asking the same question in a row have all seen the answer by the second reply.broadcast: falsesends the answer to the person who asked rather than to everybody. A bot that shouts at the whole server every time somebody types "help" is one every server turns off within a day.
block-message: true swallows the original message, so the bot answers
instead of it going out. That suits the questions where the answer is the
whole conversation.
The message blocker¶
Somebody types spawn with the slash missed and the whole server watches them
fail. It is harmless and constant, and it is new players it embarrasses most -
who are exactly the players a server can least afford to embarrass.
Instead of broadcasting the mistake, they get a clickable [ /spawn ] back.
Only a message that is nothing but the word counts. spawn is a missed
slash; spawn is over that way is a sentence, and eating it would be far worse
than letting the mistake through. Commands the player has no permission for are
never suggested, because offering /ban to somebody who typed "ban" is worse
than saying nothing.
There is also a plain regex blocklist under message-blocker.blocked.patterns
for text that should never reach chat at all. That one is a blunt instrument -
the profanity and advertising filters are the polite ones.
Reactions¶
Shortcuts for the reactions of the same name. Typing the short one is the
entire point of them, so they take no argument. /reaction lists everything a
player has unlocked; the rest are perks, unlocked by permission or bought.
Buying cosmetics¶
Every chat cosmetic - text colours, name colours, icons, reactions, tags - can be unlocked two ways, and both count the same:
- A permission, from a rank or from a store that grants a node on
purchase:
emberessentials.textcolour.fire,emberessentials.tag.vip. - In-game money. Give any entry in
perks.ymlortags.ymlaprice:and it appears in/cosmeticswith a buy button. A purchase is recorded and, on the database backend, is the player's on every server.
/cosmetics (also /wardrobe) is the one screen for all of it: a tab per
kind, and each card says whether you are wearing it, own it, can buy it, or
need a rank for it. Entries without a price stay permission-only, which is
the store-sale path; the two work side by side.
What a bad word becomes¶
filters:
profanity:
action: replace
replacements: [pudding, cat, biscuit, waffle, noodle, muffin,
banana, sock, goose, trumpet, kitten, pickle]
words: [fuck, shit, bitch, cunt, prick, wanker, bastard]
action |
Result |
|---|---|
replace |
what the Pudding is this |
mask |
what the **** is this |
block |
The message never arrives |
A replacement is picked at random per word, not per message - two swear words in one line becoming two different silly words is the joke working. Capitalisation is added for you.
Matching normalises first, so f-u-c-k and fu(k are the same word. Keep the
list short and specific; long lists catch innocent ones. Anything caught
wrongly goes in profanity.allow.
Slurs are a separate list¶
This is deliberate, and it is the one place we would push back on "just replace everything".
Turning a slur into Pudding still lets somebody say it and watch the room
react - which is most of why they said it. The filter becomes part of the joke,
and the person gets exactly what they wanted. Refusing the message does not.
So the severe list has its own action, defaulting to block, and it is checked
first: a message containing a slur is refused even when ordinary swearing in
the same line would only have been swapped out.
You can set it to mask if you would rather. There is no replace for this
list, for the reason above.
Changing it in game¶
The Filters tile shows every filter as something you can click, and the
swearing tile shows a worked example of what the current setting does to a
sentence. A screen that says REPLACE tells you nothing; one that says
what the Pudding is this tells you whether you want it.
Changes are written straight to chat.yml, so a setting changed during an
incident is still set after a crash.
The word lists themselves stay in the file. Editing a word list in a nine-slot grid is worse than editing a file, and the screen says so rather than pretending otherwise.
In pictures¶
What it looks like in game. Every shot is from a live server, unedited apart from cropping.






