春までRoblox — 第1回ブログ
テーマは Robloxのメモリー制限とユーザー毎データ保持の方法 です。
🔹 Robloxのメモリー制限の背景
-
サーバー側 (約6.4GB)
多数のプレイヤーを同時に扱うため、膨大なデータを保持する必要があります。ワークスペースのオブジェクト、スクリプト、物理演算、プレイヤーごとの状態などを一括管理するため「共有データ」だけでなく、差分やシミュレーション用の情報も含まれます。 -
クライアント側 (約100MB)
個々のプレイヤーに必要なデータのみを受け取ります。表示用のアセット、ローカルスクリプト、UI、プレイヤー自身の状態など。端末性能やネットワーク帯域を考慮して制限が厳しく設定されています。
👉 「共有データ」という観点で考えると、サーバーも100MB+αでよいのでは?という発想は理にかなっています。しかし実際には プレイヤー数×差分データ+シミュレーション領域 が必要になるため、6.4GBという枠が設定されています。
🔹 DelphiからRoblox(Lua)へのデータ定義移植
Delphiの record や const を Roblox(Lua) に移す場合は以下のように書き換えます。
-- 定数定義
local Const = {
FieldMax = 20,
Magnification = 40,
CubesMax = 320000,
CubesUndoMax = 32000,
CameraS = 150,
CameraM = 200,
CameraL = 320,
LightDark = 0.4,
LightMiddle = 0.7,
LightLight = 1.0
}
-- レコード型をLuaのtableで表現
local function Cube(x,y,z,u,child,state,range)
return {
x = x or 0, y = y or 0, z = z or 0,
u = u or 0, child = child or 0,
state = state or 0, range = range or 0
}
end
local function CubeUndo(x,y,z,w,h,d,child,state,range,groupId)
return {
x = x or 0, y = y or 0, z = z or 0,
w = w or 0, h = h or 0, d = d or 0,
child = child or 0, state = state or 0,
range = range or 0, groupId = groupId or 0
}
end
👉 Delphiの record は Luaの table、const は local Const = {}、Array[...] of は Luaの配列で代替します。
🔹 Robloxでユーザー毎データを持たせる方法
1. プレイヤーごとのデータ領域を用意する
local PlayerData = {}
game.Players.PlayerAdded:Connect(function(player)
PlayerData[player.UserId] = {
Cubes = {},
CubeUndo = {}
}
end)
game.Players.PlayerRemoving:Connect(function(player)
PlayerData[player.UserId] = nil
end)
2. Cube / CubeUndo の生成関数(共通器)
local function Cube(x,y,z,u,child,state,range)
return {x=x or 0, y=y or 0, z=z or 0,
u=u or 0, child=child or 0,
state=state or 0, range=range or 0}
end
local function CubeUndo(x,y,z,w,h,d,child,state,range,groupId)
return {x=x or 0, y=y or 0, z=z or 0,
w=w or 0, h=h or 0, d=d or 0,
child=child or 0, state=state or 0,
range=range or 0, groupId=groupId or 0}
end
3. ユーザー毎に追加する関数
local function AddCubeForPlayer(player, cube)
table.insert(PlayerData[player.UserId].Cubes, cube)
end
local function AddCubeUndoForPlayer(player, cubeUndo)
table.insert(PlayerData[player.UserId].CubeUndo, cubeUndo)
end
4. イベントは一本化して利用する
game.Players.PlayerAdded:Connect(function(player)
PlayerData[player.UserId] = { Cubes = {}, CubeUndo = {} }
local c = Cube(1,2,3,10,0,1,0)
AddCubeForPlayer(player, c)
local cu = CubeUndo(1,2,3,10,10,10,0,1,0,123)
AddCubeUndoForPlayer(player, cu)
end)
game.Players.PlayerRemoving:Connect(function(player)
PlayerData[player.UserId] = nil
end)
🔹 イベントドリブンの仕組み
game.Players.PlayerAddedは「新しいプレイヤーが参加したとき」に自動的に発火するイベント。- 引数
playerには参加したプレイヤーのオブジェクトが渡される。 - これにより「ユーザー毎にCubeデータを初期化する」処理が自然にイベントドリブンで行える。
- 対になるイベントは
game.Players.PlayerRemoving。退出時にデータを破棄するのが一般的。
🔹 まとめ
- サーバーは 共有データ+プレイヤー差分+シミュレーション領域 を持つため6.4GBが必要。
- Delphiの定義はLuaの
tableとlocal Constに移せる。 - ユーザー毎データは
PlayerData[userId]に保持し、イベント一本化で管理する。
📖 以上を第1回目のブログ記事「春までRoblox」としました。
次回は「Cubeデータをゲーム内のPartに同期させる方法」をテーマにすると、さらに実践的になります。