いいテーマ出してきたね。Robloxの「IPCっぽいもの」をレイヤー別に整理して、最小の雛型だけ並べてみるよ。
全体マップ
| レイヤー | 主な手段 | 用途ざっくり |
|---|---|---|
| 同一マシン・同一側 | BindableEvent / BindableFunction | スクリプト間イベント・関数呼び出し |
| クライアント⇔サーバー | RemoteEvent / RemoteFunction | プレイヤー操作、結果返却など |
| サーバー⇔サーバー | MessagingService | 別サーバー間の通知・同期 |
| サーバー内共有 | MemoryStoreService(Queue等) | 一時的な共有状態・ジョブキュー |
1. 同じ側のスクリプト間
BindableEvent(非同期・一方向)
配置: ReplicatedStorage でも ServerScriptService でもOK(同じ側ならよい)
-- Explorerで BindableEvent を作成して "MyEvent" と命名
-- 送信側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyEvent = ReplicatedStorage:WaitForChild("MyEvent")
MyEvent:Fire("hello", 123)
-- 受信側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyEvent = ReplicatedStorage:WaitForChild("MyEvent")
MyEvent.Event:Connect(function(msg, num)
print("received:", msg, num)
end)
BindableFunction(同期・戻り値あり)
-- Explorerで BindableFunction を作成して "MyFunc" と命名
-- 実装側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyFunc = ReplicatedStorage:WaitForChild("MyFunc")
MyFunc.OnInvoke = function(a, b)
return a + b
end
-- 呼び出し側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyFunc = ReplicatedStorage:WaitForChild("MyFunc")
local result = MyFunc:Invoke(10, 20)
print("result:", result)
2. クライアント⇔サーバー
RemoteEvent(非同期・一方向)
配置: ReplicatedStorage に RemoteEvent を作成(例: MyRemoteEvent)
-- サーバー側(ServerScriptService)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyRemoteEvent = ReplicatedStorage:WaitForChild("MyRemoteEvent")
MyRemoteEvent.OnServerEvent:Connect(function(player, msg)
print(player.Name, "says:", msg)
MyRemoteEvent:FireClient(player, "echo: " .. msg)
end)
-- クライアント側(StarterPlayerScripts)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyRemoteEvent = ReplicatedStorage:WaitForChild("MyRemoteEvent")
MyRemoteEvent.OnClientEvent:Connect(function(msg)
print("from server:", msg)
end)
MyRemoteEvent:FireServer("hello server")
RemoteFunction(同期・戻り値あり)
-- サーバー側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyRemoteFunc = ReplicatedStorage:WaitForChild("MyRemoteFunc")
MyRemoteFunc.OnServerInvoke = function(player, a, b)
return a * b
end
-- クライアント側
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MyRemoteFunc = ReplicatedStorage:WaitForChild("MyRemoteFunc")
local result = MyRemoteFunc:InvokeServer(3, 4)
print("server result:", result)
3. サーバー⇔サーバー(別ゲームサーバー間)
MessagingService(Pub/Sub)
-- ServerScriptService
local MessagingService = game:GetService("MessagingService")
local TOPIC = "GlobalNotice"
-- 購読
local success, connection = pcall(function()
return MessagingService:SubscribeAsync(TOPIC, function(message)
print("received from other server:", message.Data)
end)
end)
-- 送信
local function publishNotice(text)
local ok, err = pcall(function()
MessagingService:PublishAsync(TOPIC, text)
end)
if not ok then
warn("Publish failed:", err)
end
end
publishNotice("Hello from this server!")
4. サーバー内の一時共有・キュー
MemoryStoreService(Queueの最小例)
local MemoryStoreService = game:GetService("MemoryStoreService")
local queue = MemoryStoreService:GetQueue("JobQueue", 100)
-- ジョブ追加
local function enqueueJob(data)
local ok, err = pcall(function()
queue:AddAsync(data, 60) -- 60秒で期限切れ
end)
if not ok then
warn("enqueue failed:", err)
end
end
-- ジョブ取得
local function dequeueJob()
local ok, job = pcall(function()
return queue:ReadAsync(30) -- 30秒のロック
end)
if ok and job then
print("job:", job)
end
end
enqueueJob({type = "Example", value = 42})
dequeueJob()
「どのレイヤーで、どの境界をまたぎたいのか」を先に決めると、
- 同じ側:Bindable
- クラサバ:Remote
- サーバー間:Messaging
- サーバー内の一時共有:MemoryStore
みたいに、だいぶOSっぽく整理できます。
どのレイヤーを今いじってるか、もう少し細かく分解してみる?