Paralel Luau

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Parallelu Luau programlama modeli ile, aynı anda birden fazla başlıkta kod çalıştırabilirsiniz, bu da deneyiminizin performansını artırabilir. Daha fazla içerikle deneyiminizi genişleirken bu modeli kabul etmeniz, Luau kodlarının performansını ve güvenliğini korumak için yardımcı olabilir.

Paralel Programlama Modeli

Varsayılan olarak, kodlar seri olarak ifade edilir. Eğer deneyiminizin oyun dışı karakterler (NPC'ler), görüntü işaretleme geçişi ve prosedürsel yüksekleştirme gibi karmaşık mantığa veya içeriğe sahipse, seri ifade ile ifade edilmesi nedeniyle kullanıcılarınız için gecikme olabilir. Paral

Paralel programlama modeli ayrıca kodunuza güvenlik faydaları ekler. Kodu birden fazla başlığa bölerek, bir başlığda kodu düzenlediğinizde, diğer başlığda çalışan başka kodlara etkisi yoktur. Bu, kodunuzun tüm deneyimi bozulduğunu önlemek için ve güncellemeyi yayınladığınızda kullanıcılar için canlı sun

Paralel programlama modelini kabul etmek, her şeyi birden fazla bağlantıda yerleştirmek demek değildir. Örneğin, Sunucu-Taraflı Raycasting Geçerlilik Doğrulaması, her bir kullanıcıyı uzaktan bir etkinlik oluşturur, ancak global özellikleri değiştirmek için başlangıç kodunu seri olarak yeniden çalıştırmayı gerektirir, bu da

Genellikle istediğiniz çıktıyı elde etmek için seri ve paralel fazlarını birleştirmeniz gerekir, çünkü şu anda paralel olarak desteklenmeyen bazı işlemler yüzünden girişleri değiştirme gibi girişleri değiştirme gibi girişleri değiştirme gibi girişleri değiştirme gibi girişleri değiştirme gibi girişleri değ

Kodu Birden Fazla İşlemciye Ayrılması

Deneyiminizin kodlarını birden fazla işlemci üzerinde aynı anda yürütmek için onları aktörler altındaki farklı aktörler içinde mantıksal parçalara bölmelisiniz. Aktörleri Actor ile temsil edilir. Onlar yükleme izolasyonunun üzerinde çalış

Aktör İнstanslarını Yerleştirme

Aktörleri doğru kapsayan kapsayıcılar veya NPC'ler ve Işınlayıcılar gibi 3D entitelerinizin en üst seviye instans türlerini değiştirmek için kullanabilirsiniz, bunlara kayıt ekleyin.

An example of a Script under an Actor

Çoğu durumda, bir aktörü diğer bir aktörün çocuğu olarak veri modelinde yerleştirmeyin. Ancak, özel kullanım vakası için birkaç aktör içine gömülü bir senaryo yerleştirmeye karar verirseniz, senaryo en yakın atalet aktörü tarafından sahiptir.

A tree of actors and scripts that shows how a script is owned by its closest actor

Threadlerin Desincronizasyonu

Aktörler altında kodları seri olarak paralel olarak yürütme yeteneği verir, ancak varsayılan olarak kod hala tek işlemci üzerinde seri olarak yürütülür, bu da çalıştırma sözleşme imzalamaartırmaz. Çift şeritli kod yürütme için mevcut coroutine'ın üstünl

Alternatif olarak, bir sinyal çağrısı planladığınızda RBXScriptSignal:ConnectParallel() yöntemini kullanabilirsiniz, böylece sinyal çağrısının tetiklenmesi durumunda hemen kodunuzu paralel olarak çalıştırabilirsiniz. Sinyal çağrısı içinde task.desynchronize() çağırmak zorunda değilsiniz.

Bir Başlığı Des同期

local RunService = game:GetService("RunService")
RunService.Heartbeat:ConnectParallel(function()
... -- Bir devlet güncellemesi hesaplayan bazı paralel kod
task.synchronize()
... -- İnstansların durumunu değiştiren bazı seri kodlar
end)

Aynı aktörün bir parçası olan kodlar her zaman birbirleriyle ilgili olarak seri olarak yürütülür, bu yüzden birden fazla aktör gerekir. Örneğin, NPC'niz için tüm paralel destekleyici davranış kodlarını bir aktörde yerleştirirseniz, hala tek bir başlıca başlıca başlıca başlıca baş

Tek bir işlemci içinde seri olarak çalışan aktörlerin paralel kodu
Aynı anda birden fazla yerde çalışan aktörlerin paralel kodu

Thread Güvenliği

Paralel çalışma sırasında, DataModel yerleşiklerinin çoğu örneğine genellikle erişebilirsiniz, ancak bazı API özellikleri ve işlevleri okumak veya yazmak için güvenli değildir. Onları paralel kodunuzda kullanırsanız, Roblox motoru bu erişimlerin olmasını otomatik olarak algılayıp önleyebilir.

API üyelerinin bir bağlantı güvenliği seviyesi vardır, bunun paralel kodunda onları nasıl ve ne sıklıkta kullanabileceğinizi gösteren aşağıdaki grafikte gösterildiği gibi:

Güvenlik SeviyesiÖzellikler için함数lar için
Güvenli Olmayanlar Paralel olarak okunabilir veya yazılabilir.Aynı anda çağrılamaz.
Paralel Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu Okuyunuzu OkuyunuzParalel olarak okunabilir, ancak yazılamaz.Yok
Yerel Safe Aynı aktör içinde kullanılabilir; başka bir Actors tarafından paralel olarak okunabilir, ancak yazılamaz.Aynı aktörün içinde çağrılabilir; paralel olarak diğer Actors çağrılamaz.
Güvenli Okuyabilir ve yazılabilir.Çağrılabilir.

API üyeleri için API referansında Thread güvenliği etiketlerini bulabilirsiniz. Onları kullandığınızda, API çağrıları veya özellik değişiklikleri arasındaki API'lerin nasıl etkileşim kurduğunu da dikkate almalısınız. Genellikle birkaç aktörün diğer aktörlerin aynı verileri okumasına izin vermesi güvenlidir, ancak diğer aktörlerin durumunu de

Çok İşlemci Komünikasyonu

Çok çekirdekli konteyntein altında, farklı aktörlerdeki senaryolarla bağlantı kurarak veri değiştirme, görev koordinasyonu ve aktiviteyi senkronize etmeyi hala izin verebilirsiniz. Motor, kavşak iletişimi için şu kullanıcı mekanizmalarını destekler:

Kavşak iletişim ihtiyaçlarınızı karşılamak için birden fazla mekanizma destekleyebilirsiniz. Örneğin, Actor Messaging API aracılığıyla paylaşılan bir tablo gönderebilirsiniz.

Aktör Mesajları

Aktör Mesajları API, bir senaryo, seri veya paralel bir konteynte olarak, bir aktörü aynı veri modelinde gönderen bir senaryo gönderebilir. Bu API aracılığıyla iletişim asenkron olup, gönderici alıcıyı alana kadar blok etmez.

Bu API'yi kullanarak mesajları gönderirken, mesajı kategorize etmek için bir başlık tanımlanır. Her mesaj sadece tek bir aktörü gönderebilir, ancak bu aktör içeride bir mesaj bağlayabilir. Aktörün aşçıları olan sadece aktörler mesajları alabilir.

API'nin aşağıdaki yöntemleri vardır:

Aşağıdaki örnek, bir konuyu tanımlamak ve gönderici tarafından bir mesaj göndermek için Actor:SendMessage() ı nasıl kullanacağınızı gösteriyor:

Mesaj Göndericisi Örneği

-- Bir "Hoşgeldiniz" konusunda işçi aktörüne iki mesaj gönderin
local workerActor = workspace.WorkerActor
workerActor:SendMessage("Greeting", "Hello World!")
workerActor:SendMessage("Greeting", "Welcome")
print("Sent messages")

Aşağıdaki örnek, bir abone'nun paralel konumunda belli bir konu için bir çağrı bağlamak için Actor:BindToMessageParallel() ı nasıl kullanacağını gösteriyor:

Mesaj Alıcıyı Örnekleyin

-- Bu senaryonun ebeveyni olan aktörü alın
local actor = script:GetActor()
-- Selam mesajı konusunda bir geri bildirim bağlayın
actor:BindToMessageParallel("Greeting", function(greetingString)
print(actor.Name, "-", greetingString)
end)
print("Bound to messages")

Paylaşımlı Masa

SharedTable bir tablo gibi veri yapısıdır, birden fazla aktör tarafından çalışan kriptlerden erişilebilir. Örneğin, bir dizi içindeki büyük miktarda veri gerektiren ve bir dizi içindeki bir ortak paylaşımlı devleti gerektiren durumlar için kullanışlır. Örneğin, bir dizi içindeki bir ortak paylaşı

Paylaşılan bir tabloyu başka bir aktöre göndermek, verilerin kopyasını yapmaz. Bunun yerine, paylaşılan tablolar birden fazla script tarafından aynı anda güvenli ve atomik güncellemeleri sağlar. Bir aktörün paylaşılan tablosuna herhangi bir güncelleme, tüm aktörler anında görünür. Paylaşılan tablolar ayrıca kaynak kodu kopyalamak yerine yapısal payla

Doğrudan Veri Modeli İletişimi

Ayrıca, veri modelini kullanarak çok sayıda işlemci arasındaki iletişimi doğrudan kolaylaştirebilirsiniz, bu da farklı aktörlerin özellikleri veya öznitelikleri yazmasını ve ardından okumasını sağlayabilir. Ancak, thread güvenliğini korumak için, paralel olarak çalışan yazılımlar genellikle veri modeline yazılamaz. Bu neden

Örnekler

Sunucu-Taraflı Raycasting Geçerlilik

Bir savaş ve savaş deneyimine sahip olmak için, kullanıcıların silahları için raycasting'i etkinleştirmeniz gerekir. Client silahlarını simüle ettiğiyle, sunucu hit'i onaylamak zorunda kalır, bu, raycast'ları ve beklendiği karakter hızını hesaplayan bazı heuristikleri içerir ve geçmiş davranışını görüntüler.

Müşterilerin iletişim kurmak için kullandığı uzaktaki etkinliğe bağlanan tek merkezi bir senaryo kullanarak yalnızca bir tane merkezi senaryo çalıştırmak yerine, sunucu tarafında her bir çekişme onay süreci paralel olarak yürütülebilir, her kullanıcı karakterinin ayrı bir uzaktaki etkinliğe sahip olmasıyla.

Oyunun altındaki karakterin Actor kullanıcı aracılığıyla bu uzaktaki etkinliğe bağlanır ve etkinliği onaylamak için ilgili mantığı çalıştırır. Eğer mantık bir hit onayı bulursa, hasar ödenir, bu da özellikleri değiştirmeyi gerektirir, bu yüzden başlangıçta seri olarak çalışır.


local tool = script.Parent.Parent
local remoteEvent = Instance.new("RemoteEvent") -- Yeni bir uzaktan etkinliği oluştur ve aletin ebeveyni ol
remoteEvent.Name = "RemoteMouseEvent" -- Yerel kodun arayabileceği şekilde yeniden adlandır
remoteEvent.Parent = tool
local remoteEventConnection -- Uzaktan etkinlik bağlantısı için bir referans oluştur
-- Uzaktan bir olayı dinleyen işlev
local function onRemoteMouseEvent(player: Player, clickLocation: CFrame)
-- SERİAL: Seri olarak kurulum kodunu yürüt
local character = player.Character
-- Işınlanırken kullanıcının karakterini görmeyi unut
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = { character }
-- PARALEL: Raycast'ı paralel olarak yap
task.desynchronize()
local origin = tool.Handle.CFrame.Position
local epsilon = 0.01 -- Kullanıcının konumunun nesneden biraz dışında olabileceğinden ötürü ışını biraz genişletir
local lookDirection = (1 + epsilon) * (clickLocation.Position - origin)
local raycastResult = workspace:Raycast(origin, lookDirection, params)
if raycastResult then
local hitPart = raycastResult.Instance
if hitPart and hitPart.Name == "block" then
local explosion = Instance.new("Explosion")
-- SERIAL: Aşağıdaki kod aktörün dışındaki devleti değiştirir
task.synchronize()
explosion.DestroyJointRadiusPercent = 0 -- Patlamayı ölümsüz hale getirin
explosion.Position = clickLocation.Position
-- Çok sayıda aktör bir raycast'ta aynı parçayı alabilir ve onu yok etmeye karar verir
-- Bu kesinlikle güvenlidir, ancak bir yerine iki patlama sonuçlanır
-- Aşağıdaki çift kontrol, ifadeyi ilk olarak bu bölüme ulaştığından emin
if hitPart.Parent then
explosion.Parent = workspace
hitPart:Destroy() -- Yok et onu
end
end
end
end
-- Bazı kurulum kodlarının paralel olarak çalışmasını sağlayan ilk sinyali bağlayın, çünkü bazı kurul kodlarının paralel olarak çalışmasını sağlayan ilk sinyali bağlayın.
remoteEventConnection = remoteEvent.OnServerEvent:Connect(onRemoteMouseEvent)

Sunucu-Taraflı Prosedürlü Toprak Oluşturma

Geniş bir deneyim için dünyayı dinamik olarak doldurabilirsiniz. Prosedürsel oluşturma genellikle nesne yerleştirme, malzeme kullanımı ve voxel doldurma için oldukça karmaşık hesapları yapar. Yüksek performanslı oluşturma kodu paralel olarak yürütülürse işlem gücünü artırabilir. Aşağıdaki kod örneği içerir.


-- Paralel yürütme aktörlerin kullanımını gerektirir
-- Bu kod kendini klonlar; orijinal, işlemeyi başlatır, klonlar ise işçi olarak davranır
local actor = script:GetActor()
if actor == nil then
local workers = {}
for i = 1, 32 do
local actor = Instance.new("Actor")
script:Clone().Parent = actor
table.insert(workers, actor)
end
-- Tüm aktörleri kendi altındaki ebeveyn
for _, actor in workers do
actor.Parent = script
end
-- Aktörlere mesajlar göndererek yer oluşturmak için talimat verin
-- Bu örnekte, aktörler rastgele seçilir
task.defer(function()
local rand = Random.new()
local seed = rand:NextNumber()
local sz = 10
for x = -sz, sz do
for y = -sz, sz do
for z = -sz, sz do
workers[rand:NextInteger(1, #workers)]:SendMessage("GenerateChunk", x, y, z, seed)
end
end
end
end)
-- Orijinal skriptten çıkış; geri kalan kod her aktörde çalışır
return
end
function makeNdArray(numDim, size, elemValue)
if numDim == 0 then
return elemValue
end
local result = {}
for i = 1, size do
result[i] = makeNdArray(numDim - 1, size, elemValue)
end
return result
end
function generateVoxelsWithSeed(xd, yd, zd, seed)
local matEnums = {Enum.Material.CrackedLava, Enum.Material.Basalt, Enum.Material.Asphalt}
local materials = makeNdArray(3, 4, Enum.Material.CrackedLava)
local occupancy = makeNdArray(3, 4, 1)
local rand = Random.new()
for x = 0, 3 do
for y = 0, 3 do
for z = 0, 3 do
occupancy[x + 1][y + 1][z + 1] = math.noise(xd + 0.25 * x, yd + 0.25 * y, zd + 0.25 * z)
materials[x + 1][y + 1][z + 1] = matEnums[rand:NextInteger(1, #matEnums)]
end
end
end
return {materials = materials, occupancy = occupancy}
end
-- Çalıştırılır paralel yürütme konteynerinde çağrılacak çağrıyı bağlayın
actor:BindToMessageParallel("GenerateChunk", function(x, y, z, seed)
local voxels = generateVoxelsWithSeed(x, y, z, seed)
local corner = Vector3.new(x * 16, y * 16, z * 16)
-- Şu anda, WriteVoxels() seri fazda çağrılmalı
task.synchronize()
workspace.Terrain:WriteVoxels(
Region3.new(corner, corner + Vector3.new(16, 16, 16)),
4,
voxels.materials,
voxels.occupancy
)
end)

En İyi Pratikler

Paralel programlamanın maksimum yararlarını uygulamak için, Lua kodunuzu eklerken aşağıdaki en iyi uygulamaları referans edin:

  • Uzun Hesapları Önle — Paralel olarak bile, uzun hesaplar diğer scriptlerin çalıştırılmasını bloke edebilir ve gecikmeye neden olabilir. Büyük bir hacimde uzun, tuzaklıksız çalıştırmak için paralel programlama kullanmayın.

    Diagram demonstrating how overloading the parallel execution phase can still cause lag
  • Doğru Aktör Sayısını Kullanın — En iyi sözleşme imzalamaiçin daha fazla Actors kullanın. Cihazın Actors daha düşük çekirdekleri olsa bile, granülite daha çok çekirdek arasında daha verimli yük dengelemesi sağlar.

    Demonstration of how using more actors balances the load across cores

    Bu, olabildiğince çok Class.Actor