Moud

Safety and moderation#

Moud gives every game the same tools to keep players safe: players block each other and report each other from inside a game, you ban players from your game on the website or from a script, and server scripts check chat and names against a word filter. Moud staff can also ban a player from the whole catalog or take a game down.

Blocking#

A player blocks someone from their friend's menu or a friend request in the Moud home, or with the Block button on a website profile. Blocking:

  • ends the friendship, and drops any friend request, game invite or party invite between the two
  • stops the blocked player sending friend requests or invites, and joining a party the other is in
  • is never announced to the blocked player

Blocked players are listed under Blocked in the home, with an Unblock button.

A game decides what else a block means. Hiding chat is the usual one:

luau
-- server: each player's block list, read once when they join
local blocked: { [string]: { [string]: boolean } } = {}

game.players.joined:connect(function(player)
    task.spawn(function()
        local set = {}
        for _, id in game.blocking:list(player) do
            set[id] = true
        end
        blocked[player.id] = set
    end)
end)

-- a line from someone you blocked never reaches you
general.shouldDeliver = function(message, source)
    local mine = blocked[source.player]
    return not (mine and message.source and mine[message.source.player])
end

shouldDeliver runs for every member of every line, so it reads the table instead of asking the catalog. See Chat for channels and their callbacks.

Method
game.blocking:isBlocked(player, other) true when player blocked other. other can be a player or a player id
game.blocking:list(player) the ids player blocked

Both wait for the catalog, so call them from a task. isBlocked remembers a player's list for 30 seconds. A game only sees the block lists of players on its own servers.

Bans#

A ban keeps a player out of your game. They are kicked from every server of the game at once, and every join after that is refused with your reason until the ban ends.

On the website, open your game, then Bans. Type a Minecraft name, pick how long, and give a reason the player sees when they try to join. The same page lists everyone banned now with a Lift button, and the game's moderation log. The game's owner, Moud staff and the studio members allowed to ban can use it.

From a server script:

luau
-- server
game.bans:ban(player, { duration = 3600, reason = "Griefing the spawn" })
game.bans:ban("069a79f4-44e9-4726-a5be-fca90e38aaf5") -- an offline player, for good
print(game.bans:isBanned(player))
local info = game.bans:get(player) -- { reason = "...", until = 1767225600 } or nil
game.bans:unban(player)
Method
ban(player, options?) duration in seconds, at least 60, leave it out to ban for good. reason up to 300 letters
unban(player) true when there was a ban to lift
isBanned(player) true while a ban runs
get(player) reason and until (unix seconds, missing for a ban with no end), or nil

Each takes a player or a player id and waits for the catalog. A playtest in the editor keeps bans in memory and kicks the player, so you can try the flow before publishing.

Reports#

Players report each other from the Esc menu inside a game: Report a player, pick who, pick a reason, add a note if they want. The catalog adds the game, the server and the time itself. Reports reach the game's Reports page on the website and Moud staff. From there you dismiss a report or ban the reported player, which also settles their other open reports.

A script can open the same prompt, for a report button of your own:

luau
-- server
game.reports:prompt(player)          -- player picks who
game.reports:prompt(player, other)   -- other is picked first

A player sends at most 10 reports an hour, and the same person twice in ten minutes counts once.

Text filter#

text.filter hides blocked words in text players typed, such as chat, names or signs, and gives the text back with each blocked word turned into #:

luau
-- server
local shown = text.filter(message, player) -- "what the ####"

The filter sees through capitals, accents, letters swapped for digits or symbols (sh1t, a$$), spaces or dots between letters and repeated letters. Short words only match on their own, so "classic" and "Scunthorpe" pass. Passing the player uses the word list of their game language on top of the English one. text.filter is on the server, takes up to 2000 letters and waits for the catalog; a server with no catalog gives the text back unchanged.

A game rated All ages or 9+ (see Age rating) gets a stricter filter that also hides mild words, such as "damn" or "stupid".

Staff#

Moud staff can ban a player from the whole catalog, which signs them out of Moud, kicks them from every game and refuses every join, and can take a game down, which unlists it and stops new joins. Every staff and creator moderation action, and every ban a script makes, is kept in a moderation log with who did it, what, to whom, when and why.