roblox-text-chat について
Roblox 開発者向けのチャットとテキスト安全性に関するスキルです。TextChatService、プレイヤー作成テキストのサーバー側フィルタリング、プライバシー確認、カスタムチャンネル、プレイヤーごとのポリシー制限を扱います。
主な機能
- 01TextChatService のチャット設定
- 02サーバー側のテキストフィルタリング
- 03プライバシーと配信制御
- 04カスタムチャンネル設定
- 05プレイヤーポリシー制限の確認
- 06Quick Words の活用方法
活用シーン
- 01プレイヤーが書いた看板を表示前にフィルタリング
- 02チーム、パーティー、近接チャンネルの作成
- 03ダイレクトメッセージでのプライバシー確認
- 04プレイヤーポリシーに応じた有料アイテムやリンクの制限
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ el4cteo/ roblox-skills --skill roblox-text-chatインストール後、Claude Code で/roblox-text-chatを入力して読み込まれたか確認します。
同梱ファイルreferences/chat-recipes.md
詳細
チャットとテキストの安全性
必ず守るルール(Roblox Community Standards)
- プレイヤー同士の会話は、必ず TextChatService の
TextChannels を通してください(フィルタリング、プライバシー/保護者設定、迷惑行為の報告に対応します)。従来のChatサービス/ChatServiceLua モジュールは廃止されており、チャットシステムはTextChatServiceのみです。 - あるプレイヤーが作成し、別のプレイヤーに表示されるすべてのテキスト(ペットの名前、看板、ギルド名、取引メモ、カスタム UI)は、表示前にサーバー上で
TextService:FilterStringAsyncを使ってフィルタリングする必要があります。また、後で DataStore から読み込む際にも再度フィルタリングしてください。 - 他のプレイヤーが見られる編集可能なテキスト(看板、掲示板)には、少なくとも1分のレート制限が必要です。
CanUserChatAsync/CanUsersChatAsync/CanUsersDirectChatAsyncでプライバシー設定を尊重し、ダイレクトメッセージ用チャンネルにはTextChannel:SetDirectChatRequester()を設定してください。
チャットではないもの(フィルタリング不要):自分の UI テキスト、ゲームのステータスメッセージ、自分で作成した管理者向けアナウンス。
プレイヤーが作成したテキストのフィルタリング
--!strict
local TextService = game:GetService("TextService")
-- Broadcast (e.g. a sign everyone sees). Returns nil if filtering failed: then show nothing.
local function filterForEveryone(text: string, fromUserId: number): string?
local ok, result = pcall(function()
local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PublicChat)
return filterResult:GetNonChatStringForBroadcastAsync()
end)
return if ok then result else nil
end
-- Per-recipient (respects each viewer's age/settings; e.g. a private note).
local function filterForUser(text: string, fromUserId: number, toUserId: number): string?
local ok, result = pcall(function()
local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PrivateChat)
return filterResult:GetNonChatStringForUserAsync(toUserId)
end)
return if ok then result else nil
end
return { forEveryone = filterForEveryone, forUser = filterForUser }
- プレイヤーの送信後に、サーバー上でフィルタリングしてください(キー入力ごとではありません)。その前にレート制限を設け、文字数を制限してください。
- 失敗時はフェイルクローズにしてください(何も表示しない/プレースホルダーを表示する)。未加工のテキストを表示してはいけません。
- 必要であれば未加工のテキストを保存してもかまいませんが、表示時には必ずフィルタリングしてください(フィルターや閲覧者の設定は変わるためです)。
- 数字のみや短い文字列でもフィルタリングされる場合があります(ハッシュタグが
###になるなど)。それを考慮して UI を設計してください。
TextChatService の基本
- デフォルト設定:
CreateDefaultTextChannelsはRBXGeneralとRBXSystemを作成し、CreateDefaultCommandsは組み込みコマンド(/whisper、/team、/mute、…)を追加します。ChatWindowConfiguration、ChatInputBarConfiguration、BubbleChatConfigurationで外観を設定してください(または無効にして、TextChannel:SendAsyncとTextChatService.MessageReceivedを使って独自の UI を作成してください)。 - フロー:クライアントの
TextChannel:SendAsync(text)→ 受信者ごとのサーバー側TextChannel.ShouldDeliverCallback(message, textSource)→ フィルタリング → クライアントのOnIncomingMessageコールバック → 表示。 - コールバックでは yield しないでください。
ShouldDeliverCallbackはサーバー専用です。TextChatService.OnIncomingMessageとTextChannel.OnIncomingMessageはクライアント専用です(フォーマット用)。 - システムメッセージ:クライアントで
channel:DisplaySystemMessage(text)を呼び出します(ローカルのみ)。 - カスタムチャンネル(チーム、パーティー、近接):サーバー上で
TextChatServiceの下にTextChannels を作成し、メンバーを追加するにはchannel:AddUserAsync(userId)を呼び出します。返されたTextSourceのCanSendを確認してください。
--!strict
-- Client: chat tags and colors via OnIncomingMessage (formatting only; never yields).
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
TextChatService.OnIncomingMessage = function(message: TextChatMessage)
local properties = Instance.new("TextChatMessageProperties")
local source = message.TextSource
if source then
local player = Players:GetPlayerByUserId(source.UserId)
if player and player:GetAttribute("VIP") then
properties.PrefixText = `<font color="#F5CD30">[VIP]</font> {message.PrefixText}`
end
end
return properties
end
--!strict
-- Server: a /spawn command, restricted to admins.
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
local ADMINS: { [number]: boolean } = { [123456] = true }
local command = Instance.new("TextChatCommand")
command.Name = "SpawnCommand"
command.PrimaryAlias = "/spawn"
command.Parent = TextChatService
command.Triggered:Connect(function(source: TextSource, unfilteredText: string)
if not ADMINS[source.UserId] then
return
end
local player = Players:GetPlayerByUserId(source.UserId)
print(`{player and player.Name} ran: {unfilteredText}`)
end)
詳細:近接チャット、チームチャンネル、カスタム UI、従来のチャットからの移行: references/chat-recipes.md。
Quick Words(フリーチャットが制限されている場合に連携するための、全年齢向けの安全な定型フレーズ):Creator Hub → game → Configure → Chat → Quick Words でゲーム固有のフレーズを追加できます。英語のフレーズは自動翻訳されます。最大3カテゴリー、それぞれ3~10フレーズまで設定でき、公開前に審査されます。追加するとデフォルトのカテゴリーは置き換わりますが、General は残ります。
PolicyService(ユーザーごとの制限)
PolicyService:GetPolicyInfoForPlayerAsync(player)(サーバー、pcall)は、ArePaidRandomItemsRestricted、IsPaidItemTradingAllowed、AreAdsAllowed、AllowedExternalLinkReferences、IsSubjectToChinaPolicies、IsContentSharingAllowed などのフラグを返します。プレイヤーごとに、ルートボックス、取引、広告、ソーシャルメディアへのリンク(AllowedExternalLinkReferences に記載されたプラットフォームのみ表示)を制限してください。
関連スキル
roblox-security(レート制限、検証)、roblox-ui(テキスト入力 UI)、roblox-monetization(有料ランダムアイテム)、roblox-data-stores(ユーザーテキストの保存)。