Player safety & moderation
In-game reporting, warnings, chat mutes and bans, and a review queue on the dashboard. Works in every game, with or without chat, and covers what the App Store and Google Play ask of games with user content.
Player safety is how players flag abuse and how your team deals with it. Players report each other from your game; reports land in a review queue on the dashboard; a moderator decides (dismiss, warn, mute, chat ban or ban the account); the player is told.
It works in every game, not only games with chat. Display names and guild names are user content too, so any game can use reporting and the queue. There is no add-on and no setup.
The model
- Reports. A player reports another player with a category, where they saw it, an optional comment and, in chat, the messages in question.
- One open report per pair. Reporting the same player again updates the open report (new category, comment and messages) instead of adding another, so one angry player can't flood the queue. The queue counts distinct reporters.
- Evidence is kept. A report saves a copy of the reported messages, a few messages before them for context, and the reported player's name at that moment. Deleting a message, retention or a rename can't erase what was reported.
- Restrictions. A
warning(shown to the player until they acknowledge it), achat_mute(can read chat, can't post) or achat_ban(no chat at all). Mutes and bans can end at a set time or last until lifted. A full account ban is the existing player ban. - Test and live are separate. Players can only report players in their own environment, and the queue filters by environment.
Reporting from your game
Add a Report button wherever players see each other: profiles, leaderboards, guild pages and chat messages.
const report = await kraty.moderation.report({
targetExternalPlayerId: 'player_99',
category: 'harassment', // see the list below
context: 'chat', // chat | profile | guild | gameplay | other
comment: 'keeps insulting me', // optional, up to 1,000 characters
conversationId, // with messageIds: the chat they are in
messageIds: [badMessage.messageId], // up to 20, all sent by the reported player
});
// report: { reportId, status: 'open', category, context, createdAt, ... }Categories: spam, harassment, hate_speech, sexual_content,
violence, self_harm, cheating, impersonation,
inappropriate_name, other. Pass guildId when the report is about a
guild (its name or description).
Rules:
- A player can't report themselves (
cannot_report_self). - Each reported message must be one the reported player sent in that conversation, and one the reporter could see.
messageIdsneed chat to be on in the game. Reports without messages work in any game.- A player can file up to 20 reports a day
(
429 report_limit_reached).
Players can follow what happened to their reports. They see the status
(open, resolved or dismissed), never the decision or your notes:
const mine = await kraty.moderation.reports({ limit: 20 });Pair reporting with blocking: kraty.friends.block(...) hides the two
players from each other's search and presence, removes any friendship,
and in chat refuses direct messages both ways and hides each player's
messages from the other. See Friends.
Tell the player
When a player is warned, muted or chat-banned, your game should say so.
moderation.status() returns what is in force:
const status = await kraty.moderation.status();
// { canChat, canPost, mutedUntil, chatBannedUntil, restrictions: [...] }
for (const r of status.restrictions) {
if (r.kind === 'warning') {
await showWarning(r.reason); // "Be nice to other players"
await kraty.moderation.acknowledgeWarning(r.restrictionId);
}
}
if (!status.canPost && status.mutedUntil) showBanner(`You can chat again at ${status.mutedUntil}`);- A warning stays in
restrictionsuntil the player acknowledges it. - Mutes and chat bans stay while they are in force.
nullinmutedUntilorchatBannedUntilmeans "until lifted". - In chat, the live stream sends
restrictionandrestriction_liftedas they happen, andkraty.chat.config()includes the samestatus.
Auto-mute
In games with chat, Kraty can mute a player automatically while they
wait for review: once 3 different players report them within 24
hours, they are muted for 24 hours (all three numbers are yours to
change, under Auto-mute on the chat settings page). The mute shows
with source: "auto". A moderator can lift it, or keep it by deciding
on the reports.
Reviewing reports
Open Live ops โ Moderation. The sidebar shows how many reports are open.
Reported accounts lists one row per reported player, not one per report: number of reports and distinct reporters, categories, when they were first and last reported, and any restriction already in force. Sort by Most reported, Oldest or Newest, and filter by status, category, environment or player.
Four tiles at the top track how fast you respond: Open reports, Players with open reports, Oldest open report and Resolved in the last 7 days. Keep the oldest open report short: the stores expect timely responses.
A player's case page has everything needed to decide:
- Reports, each with its comment and the saved evidence (the reported messages highlighted, with context).
- Restriction history.
- Recent messages the player sent, as written and as filtered.
- How many reports the player filed themselves in the last 30 days (a hint for false reporting).
- Decision.
| Decision | What happens |
|---|---|
| Dismiss | Nothing was wrong. Reports close as dismissed. |
| No action | Reports close as resolved, no restriction. |
| Warn | A warning with your reason, shown to the player. |
| Mute | A chat mute: 1 hour, 24 hours, 7 days or a custom length. |
| Chat ban | A chat ban for a set time or until lifted. |
| Ban account | The account ban: player writes (events, rewards, chat) answer player_banned. |
Each decision closes all of the player's open reports at once (or only the ones you pick). You can also delete the player's messages in the same step, and add an internal note. The reason you type for warn, mute and chat ban is what the player sees.
The Restrictions tab lists every warning, mute and chat ban in force, filterable by kind, with Lift to end one early. A new restriction of the same kind replaces the active one (warnings stack).
Who can moderate
| Role | Can do |
|---|---|
| Admin, Debugger | Everything on this page, and read conversations. |
| Moderator | Review reports, decide, restrict and lift, delete chat messages, moderate guilds, ban players, write player notes, read conversations. No game configuration and no revenue. |
| QA | Sees the queue; acts on test players and test conversations only. |
| Other roles | No access to reports or private messages. |
Moderator is the role to give community or content managers. Assign it on the studio's Members page.
From your backend
Your backend can work the same queue, for example to plug in your own review tool or an anti-cheat system. The server API works in the API key's environment.
const open = await kratyServer.moderation.reports({ status: 'open' });
const kase = await kratyServer.moderation.playerCase('player_99');
await kratyServer.moderation.resolve('player_99', {
decision: 'mute',
durationHours: 24,
reason: 'Harassing other players',
note: 'first offence',
deleteMessageIds: [messageId],
});
// Restrictions without a report (an anti-cheat hit, a cooldown).
const r = await kratyServer.moderation.restrict('player_99', { kind: 'chat_mute', durationHours: 1, reason: 'Spam' });
const history = await kratyServer.moderation.restrictions('player_99');
await kratyServer.moderation.lift(r.restrictionId);Restrictions your backend puts in place show with source: "server".
See the Node and
Python server SDKs.
Webhooks: moderation.report_created, moderation.report_resolved,
player.restricted and player.restriction_lifted (plus player.banned
for account bans). See Webhooks.
App Store and Google Play checklist
Apple's App Review Guideline 1.2 (User-Generated Content) and Google Play's User Generated Content policy apply to games where players can post things others see: chat, display names, guild names. In short, they ask for the items below. Here is what Kraty gives you for each one, and what your game still has to do.
| The stores ask for | Kraty gives you | Your game still needs |
|---|---|---|
| A way to filter objectionable content | The chat profanity filter (built-in list, your own words, always mode for public channels) and the guild name word list | To turn chat on with sensible filter modes, and to filter any other user content you host yourself |
| A way to report offensive content and users | kraty.moderation.report(...) with categories, comments and message evidence | A Report button on profiles, chat messages and guild pages |
| Timely action on reports | The Moderation queue, the response-time tiles, decisions, and auto-mute | People who review the queue regularly |
| A way to block abusive users | kraty.friends.block(...), which also hides chat both ways | A Block button, and a list where players can unblock |
| Telling players about action taken | kraty.moderation.status() and the restriction stream event | Screens that show warnings, mutes and bans |
| Published contact information | Not provided by Kraty | Your support contact in the game and on the store listing |
| Terms that ban objectionable content, accepted by players (Google Play) | Not provided by Kraty | Your terms of use or community rules, and a way for players to accept them |
This is a summary to help you plan, not legal advice, and it does not guarantee approval. Store policies change: read the current App Review Guidelines and Google Play's User Generated Content policy before you submit.
SDK availability
The TypeScript SDK has kraty.moderation (report, reports, status,
acknowledgeWarning), documented above and in the
TypeScript SDK reference. Unity
(kraty.Moderation) and Flutter (kraty.moderation) have the same
methods. The endpoints are in the SDK API reference.