Kraty

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), a chat_mute (can read chat, can't post) or a chat_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.
  • messageIds need 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 restrictions until the player acknowledges it.
  • Mutes and chat bans stay while they are in force. null in mutedUntil or chatBannedUntil means "until lifted".
  • In chat, the live stream sends restriction and restriction_lifted as they happen, and kraty.chat.config() includes the same status.

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.
DecisionWhat happens
DismissNothing was wrong. Reports close as dismissed.
No actionReports close as resolved, no restriction.
WarnA warning with your reason, shown to the player.
MuteA chat mute: 1 hour, 24 hours, 7 days or a custom length.
Chat banA chat ban for a set time or until lifted.
Ban accountThe 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

RoleCan do
Admin, DebuggerEverything on this page, and read conversations.
ModeratorReview reports, decide, restrict and lift, delete chat messages, moderate guilds, ban players, write player notes, read conversations. No game configuration and no revenue.
QASees the queue; acts on test players and test conversations only.
Other rolesNo 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 forKraty gives youYour game still needs
A way to filter objectionable contentThe chat profanity filter (built-in list, your own words, always mode for public channels) and the guild name word listTo turn chat on with sensible filter modes, and to filter any other user content you host yourself
A way to report offensive content and userskraty.moderation.report(...) with categories, comments and message evidenceA Report button on profiles, chat messages and guild pages
Timely action on reportsThe Moderation queue, the response-time tiles, decisions, and auto-mutePeople who review the queue regularly
A way to block abusive userskraty.friends.block(...), which also hides chat both waysA Block button, and a list where players can unblock
Telling players about action takenkraty.moderation.status() and the restriction stream eventScreens that show warnings, mutes and bans
Published contact informationNot provided by KratyYour support contact in the game and on the store listing
Terms that ban objectionable content, accepted by players (Google Play)Not provided by KratyYour 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.

Player safety & moderation ยท Kraty