mcpField
R
roblox-text-chat

roblox-text-chat

github.com/el4cteo開発54460 回インストール2 週間前に更新
リポジトリ

roblox-text-chat について

Roblox 開発者向けのチャットとテキスト安全性に関するスキルです。TextChatService、プレイヤー作成テキストのサーバー側フィルタリング、プライバシー確認、カスタムチャンネル、プレイヤーごとのポリシー制限を扱います。

主な機能

  1. 01TextChatService のチャット設定
  2. 02サーバー側のテキストフィルタリング
  3. 03プライバシーと配信制御
  4. 04カスタムチャンネル設定
  5. 05プレイヤーポリシー制限の確認
  6. 06Quick Words の活用方法

活用シーン

  1. 01プレイヤーが書いた看板を表示前にフィルタリング
  2. 02チーム、パーティー、近接チャンネルの作成
  3. 03ダイレクトメッセージでのプライバシー確認
  4. 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)

  1. プレイヤー同士の会話は、必ず TextChatService の TextChannels を通してください(フィルタリング、プライバシー/保護者設定、迷惑行為の報告に対応します)。従来の Chat サービス/ChatService Lua モジュールは廃止されており、チャットシステムは TextChatService のみです。
  2. あるプレイヤーが作成し、別のプレイヤーに表示されるすべてのテキスト(ペットの名前、看板、ギルド名、取引メモ、カスタム UI)は、表示前にサーバー上で TextService:FilterStringAsync を使ってフィルタリングする必要があります。また、後で DataStore から読み込む際にも再度フィルタリングしてください。
  3. 他のプレイヤーが見られる編集可能なテキスト(看板、掲示板)には、少なくとも1分のレート制限が必要です。
  4. 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(ユーザーテキストの保存)。

コメント