Roblox oyunları varsayılan olarak çok oyunculudur, bu nedenle tüm oyunlar sunucu ile oyuncuların bağlı istemcileri arasında iletişim kurar. En basit durumda, oyuncular karakterlerini hareket ettirdikçe, belirli Humanoid özellikleri, örneğin durumlar, sunucuya iletilir ve sunucu bu bilgiyi diğer bağlı istemcilere aktarır.
Uzaktan olaylar ve geri çağırmalar, istemci-sunucu sınırında iletişim kurmanıza olanak tanır:
- RemoteEvents tek yönlü iletişimi (bir istek gönderme ve cevap beklememe) sağlar.
- UnreliableRemoteEvents sürekli değişen veya oyunun durumu için kritik olmayan veriler için tek yönlü iletişim sağlar. Bu olaylar, sıralama ve güvenilirlikten ödün vererek gelişmiş ağ performansı sunar.
- RemoteFunctions iki yönlü iletişimi (bir istek gönderme ve alıcıdan bir yanıt alınana kadar bekleme) sağlar.
Daha sınırlı kullanım alanlarına sahip olan bindable events ile karşılaştırıldığında, uzaktan olaylar ve işlevlerin kullanım senaryoları oldukça fazladır:
- Oyun Oynama - Bir oyuncunun bir seviyenin sonuna ulaşması gibi temel oyun, uzaktan bir olaya ihtiyaç duyabilir. Bir istemci betiği sunucuya bildirir ve sunucu betikleri oyuncunun konumunu sıfırlar.
- Sunucu Doğrulama - Bir oyuncu bir iksir içmeye çalıştığında, gerçekten o iksire sahip mi? Adalet sağlamak için, sunucu oyunun gerçeği olmalıdır. Bir istemci betiği, oyuncunun bir iksir içtiğini sunucuya bildirmek için bir uzaktan olayı kullanabilir ve ardından sunucu betikleri, oyuncunun gerçekten o iksire sahip olup olmadığını ve herhangi bir avantaj verip vermemeye karar verebilir.
- Kullanıcı Arayüzü Güncellemeleri - Oyun durumu değiştikçe, sunucu betikleri puanlar, hedefler vb. değişiklikleri istemcilere bildirmek için uzaktan olaylar kullanabilir.
- Oyun İçi Pazar satın alımları - Uzaktan işlevler kullanan bir örnek uygulama için İstek Abonelik Satın Almaları sayfasına bakınız.
Hızlı referans
Aşağıdaki tablolar, RemoteEvents ve RemoteFunctions kullanarak istemci ve sunucu arasında nasıl iletişim kurulacağına dair hızlı bir referans olarak hizmet eder.
| İstemci → Sunucu | |
|---|---|
| İstemci | RemoteEvent:FireServer(args) |
| Sunucu | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
| Sunucu → İstemci | |
| Sunucu | RemoteEvent:FireClient(player, args) |
| İstemci | RemoteEvent.OnClientEvent:Connect(function(args)) |
| Sunucu → Tüm İstemciler | |
| Sunucu | RemoteEvent:FireAllClients(args) |
| İstemci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Uzaktan olaylar
Bir RemoteEvent nesnesi, yanıt beklemeden istemci-sunucu sınırında asenkron, tek yönlü iletişimi kolaylaştırır.
Studio'daki Explorer penceresi aracılığıyla yeni bir RemoteEvent oluşturmak için:
- RemoteEvent'i eklemek istediğiniz kapsayıcının üzerine gelin. Hem sunucu hem de istemci erişimini sağlamak için, hem tarafların görebileceği bir yerde olmalıdır, örneğin ReplicatedStorage, ancak bazı durumlarda Workspace veya bir Tool içinde saklamak uygundur.
- Kapsayıcının adının sağında görünen ⊕ butonuna tıklayın ve bir RemoteEvent örneği ekleyin.
- Örneği amacını açıklayacak şekilde yeniden adlandırın.
Bir RemoteEvent oluşturduktan sonra, istemciden sunucuya, sunucudan istemciye veya sunucudan tüm istemcilere tek yönlü iletişim sağlaması mümkündür.



İstemci → sunucu
Bir LocalScript kullanarak, bir RemoteEvent üzerinde FireServer() yöntemini çağırarak sunucuda bir olayı tetikleyebilirsiniz. FireServer() yöntemine argümanlar geçtiğinizde, bunlar sunucudaki olay yöneticisine belirli sınırlamalarla iletilir. Olay yöneticisinin ilk parametresi her zaman çağrıyı yapan istemcinin Player nesnesidir ve ek parametreler ardından gelir.
| İstemci | RemoteEvent:FireServer(args) |
| Sunucu | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
Aşağıdaki Script, sunucuda yeni bir Part oluşturmak için OnServerEvent ile bir olay yöneticisi bağlar. Buna karşılık gelen LocalScript, istenilen Color ve Position ile RemoteEvent örneği üzerinde FireServer() çağrısını yapar.
Olay Bağlantısı - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Uzaktan olay örneğine referans al
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " uzaktan olayı tetikledi")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Olayı bağla
remoteEvent.OnServerEvent:Connect(onCreatePart)
Olayı Tetikleme - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Uzaktan olay örneğine referans allocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Uzaktan olayı tetikle ve ek argümanlar geçirremoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
Sunucu → istemci
Bir Script kullanarak, bir istemci üzerinde olayı tetiklemek için FireClient() yöntemini çağırabilirsiniz. FireClient() yönteminin ilk argümanı, etkinliğe yanıt vermek istediğiniz istemcinin Player nesnesidir ve ek argümanlar istemciye belirli sınırlamalarla iletilir. Olay yöneticisinin ilk argümanı olarak Player nesnesi gerekmemektedir çünkü istemci üzerinde Players.LocalPlayer ile oyuncuyu belirleyebilirsiniz.
| Sunucu | RemoteEvent:FireClient(player, args) |
| İstemci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Aşağıdaki LocalScript, OnClientEvent olayına bir etkinlik yöneticisi bağlar. Buna karşılık gelen Script, sunucuya gelen oyuncuları dinleyerek her biri için FireClient() çağrısını belirli verilerle yapar.
Olay Bağlantısı - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Uzaktan olay örneğine referans al
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[İstemci] Olaya oyuncu tarafından yanıt verildi", player.Name)
print(maxPlayers, respawnTime)
end
-- Olayı bağla
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Olayı Tetikleme - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Uzaktan olay örneğine referans al
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sunucuya gelen oyuncuları dinle ve her birine uzaktan olay gönder
local function onPlayerAdded(player)
print("[Sunucu] Oyuncuya olayı tetikle", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Sunucu → tüm istemciler
Bir Script kullanarak, tüm istemciler üzerinde olayı tetiklemek için FireAllClients() yöntemini çağırabilirsiniz. FireClient()'dan farklı olarak, FireAllClients() yöntemi, tüm istemcilere RemoteEvent ateşlemek için bir Player nesnesi gerektirmez.
| Sunucu | RemoteEvent:FireAllClients(args) |
| İstemci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Aşağıdaki LocalScript, kalan geri sayım süresini göstermek için OnClientEvent olayına bir etkinlik yöneticisi bağlar. Buna karşılık gelen Script, her saniye döngüde FireAllClients() çağırarak tüm istemciler için RemoteEvent'i ateşler.
Olay Bağlantısı - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Uzaktan olay örneğine referans al
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Olayı bağla
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Olayı Tetikleme - Scriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Uzaktan olay örneğine referans allocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local countdown = 5-- Zaman sona erene kadar her saniye RemoteEvent'ı ateşlefor timeRemaining = -1, countdown doremoteEvent:FireAllClients(countdown - timeRemaining)task.wait(1)end
Uzaktan geri çağırmalar
Bir RemoteFunction nesnesi, istemci-sunucu sınırında senkron, iki yönlü iletişimi kolaylaştırır. Uzaktan bir işlevin göndericisi, alıcıdan bir yanıt alana kadar bekler.
Studio'daki Explorer penceresi aracılığıyla yeni bir RemoteFunction oluşturmak için:
- RemoteFunction'i eklemek istediğiniz kapsayıcının üzerine gelin. Hem sunucu hem de istemci erişimini sağlamak için, hem tarafların görebileceği bir yerde olmalıdır, örneğin ReplicatedStorage, ancak bazı durumlarda Workspace veya bir Tool içinde saklamak uygundur.
- Kapsayıcının adının sağında görünen ⊕ butonuna tıklayın ve bir RemoteFunction örneği ekleyin.
- Örneği amacını açıklayacak şekilde yeniden adlandırın.
Bir RemoteFunction oluşturduktan sonra, bu işlev, istemci ve sunucu veya sunucu ve istemci arasında iki yönlü iletişimi kolaylaştırabilir.


İstemci → sunucu → istemci
Bir LocalScript kullanarak, bir sunucuda bir işlev çağırmak için InvokeServer() yöntemini çağırabilirsiniz. Bir uzaktan olay ile karşılaştırıldığında, RemoteFunction'u kullanan LocalScript, geri çağırma dönene kadar bekler. InvokeServer() yöntemiyle geçirdiğiniz argümanlar, belirli sınırlamalarla OnServerInvoke geri çağırmasına iletilir. Aynı RemoteFunction için birden fazla geri çağırma tanımlarsanız, yalnızca son tanım çalıştırılır.
| İstemci | RemoteFunction:InvokeServer(args) |
| Sunucu | RemoteFunction.OnServerInvoke = function(player, args) |
Aşağıdaki Script, OnServerInvoke aracılığıyla geri çağırma işlevini tanımlar ve istenilen Part'ı döndürür. Buna karşılık gelen LocalScript ise istenilen parçanın rengi ve konumunu tanımlayan ek argümanlarla InvokeServer()'ı çağırır.
Geri Çağırma Bağlantısı - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Uzaktan işlev örneğine referans al
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geri çağırma işlevi
local function createPart(player, partColor, partPosition)
print(player.Name .. " yeni bir parça istedi")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Geri çağırma işlevi olarak işlevi ayarla
remoteFunction.OnServerInvoke = createPart
Olay Çağrısı - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Uzaktan işlev örneğine referans allocal remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")-- Geri çağırmayı tetiklerken bir renk ve pozisyon geçirlocal newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))-- Döndürülen parça referansını çıktı olarak verprint("Sunucu istenen parçayı oluşturdu:", newPart)
Sunucu → istemci → sunucu
Bir Script kullanarak, bir istemci üzerinde bir işlev çağırmak için InvokeClient() yöntemini çağırabilirsiniz, ancak bunun bazı ciddi riskleri vardır:
- Eğer istemci bir hata fırlatırsa, sunucu da bu hatayı fırlatır.
- İstemci işlemi yapılırken bağlantısını keserse, InvokeClient() bir hata fırlatır.
- İstemci bir değer döndürmezse, sunucu sonsuza kadar bekler.
İki yönlü iletişim gerektirmeyen işlemler için, örneğin bir GUI güncellemesi yapmak gibi, bir RemoteEvent kullanın ve sunucudan istemciye iletişim kurun.
Argüman sınırlamaları
Bir RemoteEvent ateşlediğinizde veya bir RemoteFunction'ı çağırdığınızda, geçtiğiniz argümanlar etkinlik veya geri çağırma işlevine iletilir. Herhangi bir Roblox nesne türü, Enum, Instance veya diğerleri gibi geçilebilir, ayrıca sayı, dize ve boolean gibi Luau türleri de geçilebilir, ancak aşağıdaki sınırlamaları dikkatlice gözden geçirmeniz gerekmektedir.
Dize olmayan indeksler
Geçilen bir tablonun indekslerinden herhangi biri Instance, userdata veya function gibi dize olmayan türlerse, Roblox otomatik olarak bu indeksleri dizelere dönüştürür.
Olay Bağlantısı - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> dize
end
end
-- Olayı bağla
remoteEvent.OnClientEvent:Connect(onEventFire)
Olayı Tetikleme - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sunucuya gelen oyuncuları dinle ve her birine uzaktan olay gönder
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Geçilen işlevler
Bir RemoteEvent veya RemoteFunction için argüman olarak dahil edilen işlevler, istemci-sunucu sınırında kopyalanmaz, bu nedenle işlevleri uzaktan iletmek imkansız hale gelir. Bunun yerine, alıcı tarafındaki sonuç argümanı nil olacaktır.
Olay Bağlantısı - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Olayı Tetikleme - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Merhaba dünya!")
end
-- İşlevi argüman olarak geçerek uzaktan olayı tetikle
remoteEvent:FireAllClients(testFunction)
Tablo dizinleme
Bir veri tablosu geçiriyorsanız, karışık bir dizi (sayısal ve dize anahtarları ile) geçmemeye dikkat edin. Bunun yerine, yalnızca anahtar-değer çiftleri (sözlük) veya yalnızca sayısal indekslerden oluşan bir tablo geçirin.
Olay Bağlantısı - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Kılıç
--> 2 = Yay
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Olayı bağla
remoteEvent.OnServerEvent:Connect(onEventFire)
Olayı Tetikleme - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Sayısal dizinli tablolocal inventoryData = {"Kılıç", "Yay"}-- Sözlük tablosulocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}remoteEvent:FireServer(inventoryData)remoteEvent:FireServer(characterData)
Tablo kimlikleri
Uzaktan olaylara/geri çağırmalara argüman olarak geçirilen tablolarda kopyalanır, yani ateşleme olayı sırasında sağlananlarla tam olarak eşdeğer olmayacaklardır. Geri döndürülen tablolarda, geri kalanlar da tam olarak aynı olmayacaklardır. Bunu, aşağıdaki kodu bir RemoteFunction üzerinde çalıştırarak gösterin ve tablo kimliklerinin nasıl farklılık gösterdiğini gözlemleyin.
Geri Çağırma Bağlantısı - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geri çağırma işlevi
local function returnTable(player, passedTable)
-- Çağrıldığında tablo kimliğini verir
print(tostring(passedTable)) --> tablo: 0x48eb7aead27563d9
return passedTable
end
-- Geri çağırma işlevi olarak işlevi ayarla
remoteFunction.OnServerInvoke = returnTable
Olay Çağrısı - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")local inventoryData = {"Kılıç", "Yay"}-- Orijinal tablo kimliğini verirprint(tostring(inventoryData)) --> tablo: 0x059bcdbb2b576549local invokeReturn = remoteFunction:InvokeServer(inventoryData)-- Geri dönen tablo kimliğini verirprint(tostring(invokeReturn)) --> tablo: 0x9fcae7919563a0e9
Metatables
Bir tablonun metatable'ı varsa, transfer sırasında tüm metatable bilgileri kaybolur. Aşağıdaki kod örneğinde, NumWheels özelliği Car metatables kısmına aittir. Sunucu, aşağıdaki tabloyu aldığında, truck tablosu Name özelliğine sahip ancak NumWheels özelliğine sahip olmayacaktır.
Olay Bağlantısı - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "MyTruck"}
end
-- Olayı bağla
remoteEvent.OnServerEvent:Connect(onEvent)
Olayı Tetikleme - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Metatable'ı içeren bir tablo ile etkinliği ateşleremoteEvent:FireServer(truck)
Kopyalanmayan örnekler
Bir RemoteEvent veya RemoteFunction geçerken, yalnızca göndericiye görünür olan bir değeri geçiyorsanız, Roblox bu değeri istemci-sunucu sınırında yansıtmaz ve bunun yerine nil ile geçer. Örneğin, bir Script sunucuda bir ServerStorage nesnesi geçirirse, olayı dinleyen istemci bir nil değeri alacaktır çünkü o nesne istemci için kopyalanamaz.
Olayı Tetikleme - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- İstemci ServerStorage'a erişemeyeceği için "nil" olarak alınır
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Benzer şekilde, bir LocalScript içinde bir parça oluşturursanız ve bunu bir Script nesnesine geçirmeye çalışırsanız, sunucu nil değerini görecektir çünkü parça sunucu için kopyalanamaz.
Olayı Tetikleme - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Workspace = game:GetService("Workspace")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Sunucu bu parçayı bilmediği için "nil" olarak alınırlocal clientPart = Instance.new("Part")clientPart.Parent = WorkspaceremoteEvent:FireServer(clientPart)