ClusterScriptの制限逆引きリスト
Advent Calendarの季節なので、今年もクラスター Advent Calendarに投稿です。
気づけば今年で4回目。
ClusterScriptの様々な制限について
今年もたくさんClusterScriptを書き、そしてたくさんのバグを生み出しました。
その中でよく悩まされたのが、Scriptが何らかの制限に引っかかってしまい、正常に動作しなくなることです。
Script Referenceに記載されている制限には、大きく「頻度制限」と「容量制限」があります。
「頻度制限」は、例えば $.createItem は1アイテムにつき10回/秒までしかできないよ、といったこと。
「容量制限」は、例えば _.setPlayerStorageData では10KBまでしか保存できないよ、といったこと。
そしてこの制限というのは、一人で動作確認していると見逃してしまうことも多いです。
10人とか20人、あるいはそれ以上のプレイヤーが体験することで制限に到達する、そういうことが多々ありました。
ということで、今回は制限値を意識し直すために、逆引きリストを作ってみました。
Script Referenceで配布されているindex.d.tsをClaudeに読ませて、まとめてもらいました。あまりちゃんとチェックしてないので、間違っていたり漏れていたらすいません。
データは2025/12/01時点のものです。
制限逆引きリスト
頻度制限
瞬間的な超過は可能だが平均回数は制限を下回る必要がある
最大10回/秒(ひとつのアイテムあたり)
$.createItem$.requestOwnership-
ItemHandle.send(クラフトアイテムの場合) -
PlayerHandle.send(クラフトアイテムの場合) -
_.sendTo(クラフトアイテムの場合) ItemHandle.addImpulsiveForceItemHandle.addImpulsiveTorqueItemHandle.addImpulsiveForceAtPlayerHandle.setPositionPlayerHandle.setRotationPlayerHandle.setHumanoidPosePlayerHandle.respawnPlayerHandle.addVelocityPlayerHandle.setMoveSpeedRatePlayerHandle.setJumpSpeedRatePlayerHandle.setGravityPlayerHandle.resetPlayerEffectsPlayerHandle.requestTextInputPlayerHandle.setPostProcessEffectsPlayerHandle.requestPurchase
最大3000回/秒(スペース内の全アイテム合計)
-
ItemHandle.send(ワールドアイテムの場合) -
PlayerHandle.send(ワールドアイテムの場合) -
_.sendTo(ワールドアイテムの場合)
最大5回/分(ひとつのアイテムあたり)
-
$.getOwnProducts(クラフトアイテムの場合)
最大100回/分(スペース内の全アイテム合計)
-
$.getOwnProducts(ワールドアイテムの場合)
容量制限
100byte以下
-
ItemHandle.sendのmessageType -
PlayerHandle.sendのmessageType -
_.sendToのmessageType -
$.callExternalのmeta -
$.getOwnProductsのmeta -
PlayerHandle.requestPurchaseのmeta -
PlayerHandle.requestGrantProductのmeta -
PlayerHandle.requestTextInputのmeta
200byte以下
-
PlayerHandle.requestTextInputのtitle
1000byte以下
-
ItemHandle.sendのarg(soft limit) -
PlayerHandle.sendのarg(soft limit) -
_.sendToのarg(soft limit) -
SubNode.setTextの文字列
1000byte以下 かつ 250文字以下
ASCIIは1文字あたり0.5文字として換算
-
PlayerHandle.requestTextInputで受け取るプレイヤーの入力文字列 -
$.onTextInputコールバックで受け取れる文字列
10kB以下
-
_.setPlayerStorageDataのdata
100kB以下
-
$.callExternalのrequest -
$.callExternalの外部サーバーからのresponse
配列要素数の制限
最大64個まで
-
$.setVisiblePlayersのplayers配列
リストを眺めた所感
頻度制限
$.createItem が10回/秒なのはイメージしやすいですね。自分の場合、たくさんのItemを同時に生成しなければならない時は0.1秒ごとに1個ずつ生成して、「そういう演出」であるかのように見せることが多いです。 $.onCreate でAnimationを再生したりして。
一方で、PlayerHandle系が10回/秒なのは少し注意が必要かもしれません。例えば、「たくさんのプレイヤーを同時にワープさせる」みたいな場合は、PlayerHandle.setPositionを使うと10人以上同時にワープさせられないので、対象プレイヤー全員に PlayerHandle.send してからPlayerScript側で _.setPosition するのも手ですね。
リファレンスに書かれてないけど、自分の記憶では $.setPlayerScript も10回/秒だった気がする。
容量制限
覚えておくとよいのは以下の3点だと思います。
-
ItemHandle.sendPlayerHandle.send_.sendToのargは1000byteまで(soft limit) -
_.setPlayerStorageDataのdataは10kBまで -
$.callExternalのrequestは100kBまで
例えば、PlayerStorageの内容を $.callExternal で外部サーバーに送りたい時があったとしましょう。
PlayerStorageの data の容量は10kBまでなので、100kB制限である $.callExternal の request に格納するには特に問題ない…と思いきや、 $.callExternal するためにはPlayerScriptからItemに _.sendTo しなければならず、その制限は1000byteなのです。
配列要素数の制限
$.setVisiblePlayers の players 配列の要素数が最大64個までとなっています。
ひとつのアイテムに対する可視性フィルターは64人までしか設定できない、ということですね。
スペースには25人までしか入室できないので64個もあれば十分と思うかもしれませんが、退室したプレイヤーを検知してその情報を配列から削除しておかないと、スペースが生き続ける限り要素数が増えていきます。スペースが長く残るタイプのワールドを作っている方は要注意です。
Discussion