Rojoを使用したRoblox開発(Luau)
VM内でプレーンファイルとしてRoblox体験を構築し、Rojoでプレイスファイルにコンパイルし、ユーザーから依頼があった場合にのみ、Roblox Open Cloudを通じてテストプレイスにアップロードします。ユーザーにはその言語(デフォルトはpt-BR)で応答してください。
0. 基本ルール
- APIキーを絶対に表示、出力、ログ、書き込みしないでください。
shell呼び出し内でのみ{{secret:<name>}}というボールトマーカーを使用してください。ランタイムが値を置き換え、出力から隠します。 - ユーザーから提供されたテストプレイス(universeId + placeId)にのみ公開してください。IDを推測したり、別の会話からIDを再利用したりしないでください。ユーザーが本番/公開プレイスを指定した場合は、確認のために停止してください。
- デフォルトの
versionTypeはSaved(バージョン履歴に新しいバージョンを作成し、公開はしない)です。ユーザーが明示的に公開を依頼した場合のみPublishedを使用してください。 - universeId、placeId、またはシークレット名がない場合は、
propose_questionnaire(短いフォーム1つ)で質問してください。シークレットが完全に欠けている場合は、secret_requestを呼び出してください(推奨名:ROBLOX_API_KEY)。キーをチャットで尋ねないでください。
1. Rojoのインストール(VMごとに1回)
固定リリース:Rojo 7.7.1(https://github.com/rojo-rbx/rojo/releases で新しい7.xがないか確認し、固定を変更する前にユーザーに伝えてください)。プリビルドのLinux x86_64バイナリをホームフォルダにインストールします(rootは不要):
mkdir -p "$HOME/.local/bin" && cd "$(mktemp -d)"
curl -fsSL -o rojo.zip https://github.com/rojo-rbx/rojo/releases/download/v7.7.1/rojo-7.7.1-linux-x86_64.zip
unzip -o rojo.zip && install -m 0755 rojo "$HOME/.local/bin/rojo"
export PATH="$HOME/.local/bin:$PATH"
rojo --version # 期待値: rojo 7.7.1
最初にcommand -v rojoで確認し、既に7.xが表示される場合はインストールをスキップしてください。ARM VMの場合はlinux-aarch64アセットを使用してください。ツールチェーンマネージャーが既に存在する場合の代替方法:rokit add rojo-rbx/rojo && rokit install。他のURLからインストーラを実行しないでください。
2. プロジェクト構成
my-game/
default.project.json
src/
server/ -> ServerScriptService.Server (サーバー専用コード)
client/ -> StarterPlayer.StarterPlayerScripts.Client
shared/ -> ReplicatedStorage.Shared (両側で必要なモジュール)
default.project.json:
{
"name": "my-game",
"tree": {
"$className": "DataModel",
"ServerScriptService": { "Server": { "$path": "src/server" } },
"ReplicatedStorage": { "Shared": { "$path": "src/shared" } },
"StarterPlayer": {
"$className": "StarterPlayer",
"StarterPlayerScripts": { "Client": { "$path": "src/client" } }
}
}
}
Rojoが認識するファイル命名規則:init.server.luau(フォルダ用のScript)、*.server.luau(Script)、*.client.luau(LocalScript)、プレーンな*.luau(ModuleScript)、init.luau(フォルダがModuleScriptになります)。*.rbxl、*.rbxlx、Packages/を含む.gitignoreを追加してください。フォルダにdefault.project.jsonがない場合のみプロジェクトを作成してください。既存の構成を上書きせず、それに適応してください。
3. コーディング規約
- すべてのファイルの先頭に
--!strictを付けたLuau。関数シグネチャとエクスポートされるテーブルに型を指定してください。 - 1つのModuleScriptにつき1つの責務とし、テーブルを返してください。グローバル変数、
_G、sharedは使用しないでください。requireは直接参照(script.Parent.ModuleまたはReplicatedStorage.Shared.Module)で使用してください。 - エントリーポイントは小さく保ってください:1つの
init.server.luauと、サービス/コントローラーをrequireして順に開始するクライアントエントリー。 - サービスの取得は先頭で行ってください:
local Players = game:GetService("Players")。wait/spawn/delayよりもtask.wait、task.spawn、task.delayを優先してください。Players.PlayerRemovingでプレイヤーごとの接続を切断してください。 - クライアントを決して信用しないでください。サーバーがゲーム状態(通貨、インベントリ、ダメージ、テレポート、進行度)を所有します。クライアントは意図を送信し、結果をレンダリングするだけです。
リモートセキュリティチェックリスト
- RemoteEvent/RemoteFunctionインスタンスはサーバーから
ReplicatedStorage下に固定名で作成してください。クライアントから作成しないでください。 - すべての
OnServerEvent/OnServerInvokeで、引数の数と型(typeof)を検証し、範囲をクランプし、NaN/infを拒否し、文字列長を制限し、プレイヤーが許可されているか(クールダウン、所有権、距離、生存)を確認してください。 - プレイヤーごとにレート制限(トークンバケットまたは最終呼び出しタイムスタンプ)を適用してください。リモートは、価格、ダメージ量、またはクライアントが有利に選択できる値を決して保持してはいけません。
- RemoteFunction:
InvokeClientは絶対に使用しないでください(悪意のあるクライアントがサーバースレッドをハングさせる可能性があります)。 - DataStore:
pcallでラップし、バックオフで再試行し、PlayerRemovingとgame:BindToCloseで保存してください。貴重なデータはセッションロックしてください。 - シークレットと調整用のノブはServerScriptService/ServerStorageのみに配置し、ReplicatedStorageには決して置かないでください。
4. ビルド
rojo build default.project.json -o place.rbxl
ls -l place.rbxl
まずビルドエラー($pathの欠落、不正なJSON、重複名)を修正してください。place.rbxlをコミットしないでください。selene / stylua --checkはオプションです。依頼がない限りインストールしないでください。ファイルからのみビルドされたプレイスはスクリプトの骨格です。Studioで作成されたアセット、地形、UIは既存のプレイスに存在するため、アップロードするとターゲットバージョンのコンテンツが置き換えられます。これこそが、ターゲットがテストプレイスでなければならない理由です。
5. Open Cloud経由での公開(テストプレイス)
エンドポイント(Roblox Open Cloud Place Publishing, universes v1):
POST https://apis.roblox.com/universes/v1/{universeId}/places/{placeId}/versions?versionType=Saved|Published
- ヘッダー
x-api-key: <key>;Content-Type: application/octet-stream(.rbxlバイナリ用)、application/xml(.rbxlx用)。 - ボディ:生のプレイスファイル。成功レスポンス:
{ "versionNumber": 7 }。 - APIキーには、ターゲット体験に対するWrite権限を持つ
universe-places権限が必要です(Creator Dashboardで作成)。 - HTTPSのみ。APIは一部のインスタンスタイプ(EditableImage、EditableMesh、PartOperation、SurfaceAppearance、BaseWrap)を更新しません:それらはStudioから公開するようユーザーに伝えてください。
- ドキュメント:https://create.roblox.com/docs/en-us/cloud/guides/usage-place-publishing
ボールトマーカーを使用して実行します(マーカーはシェルコマンド内に配置し、メッセージテキストには決して含めないでください):
curl -sS -X POST \
"https://apis.roblox.com/universes/v1/$UNIVERSE_ID/places/$PLACE_ID/versions?versionType=Saved" \
-H "x-api-key: {{secret:ROBLOX_API_KEY}}" \
-H "Content-Type: application/octet-stream" \
--data-binary @place.rbxl
$UNIVERSE_IDと$PLACE_IDをユーザーから提供された数値に、シークレット名を実際のボールト名に置き換えてください(secret_listで名前のみ表示)。キーを公開せずにエラーを処理してください:401/403 = キーが無効、または権限/体験が不足;404 = 間違ったuniverse/placeのペア;400 = ファイルが不正(再ビルド);429 = 待機して1回再試行。HTTPステータスとレスポンスボディのみを引用してください(これらにはキーが含まれていません)。
6. 報告
各タスクの最後に、ユーザーの言語で短い報告を行ってください:
- 変更内容(ファイルと動作)を平易な言葉で。
rojo buildの結果、公開した場合はversionNumber、使用したversionType、およびそれがテストプレイス<placeId>に送信されたこと。- Studioでテストする方法:テストプレイスを開き、バージョン履歴を開いて新しいSavedバージョンを読み込み、Play(F5)を押し、期待される出力メッセージと共に試すべき具体的な内容。
- 実行しなかったこと(ライブ公開、Studioが必要なアセットや地形など)。
7. ローカル同期オプション
ライブ編集の場合、ユーザーは自身のコンピュータでRojo Studioプラグイン(https://rojo.space/docs/v7/getting-started/installation/)を使用して`rojo serve`を実行できます。VMにはユーザーのStudioからアクセスできないため、VM内ではビルドしてOpen Cloudにアップロードする方法に留めてください。