Görev ve diyalog sistemleri Roblox'taki RPG ve macera oyunlarının omurgasını oluşturur. Zayıf mimariler ani bağlantı kopmalarında oyuncu ilerlemesini siler.
Önkoşullar için DAG grafikleri, modüler olay veriyolu (event bus), dallanan konuşma ağaçları ve DataStore bit sıkıştırma teknikleriyle hatasız görev sistemleri inşa edilebilir.
1. Yönlendirilmiş Döngüsüz Çizgeler (DAG) Olarak Görevler
Kısır döngü kilitlenmeleri olmadan zengin hikayeler kurgulama:
- Önkoşul Ağaçları: Görevler, kendisinden önceki tüm aşamalar tamamlanmadan açılmayan çizge düğümleri olarak kurgulanır.
- Dallanan ve Birbirini Dışlayan Yollar: Bir fraksiyonu seçmek zıt görev kollarını sorunsuzca devre dışı bırakır.
- Topolojik Sıralama Denetimi: Veritabanı test edilirken döngüsel kilitlenmelerin oluşması matematiksel olarak önlenir.
2. Sonlu Durum Makinesi (FSM) ile Görev Döngüsü
Hileleri engelleyen katı durum geçiş kuralları:
- 6 Temel Durum:
Kilitli ➔ Müsait ➔ Aktif ➔ Tamamlandı ➔ Ödül Alındı(GerektiğindeBaşarısız). - Sunucu Yetkisi: İstemci asla görevi tek başına bitiremez; sunucu eylemleri doğrulayıp durumu değiştirir.
- İyimser UI Geri Bildirimi: Sunucu onaylar onaylamaz arayüzde akıcı animasyonlar ve başarı sesleri oynatılır.
-- FSM Görev Yöneticisi
local QuestManager = {}
QuestManager.__index = QuestManager
local QuestDatabase = require(game.ReplicatedStorage.QuestDatabase)
function QuestManager.new(player, profileData)
local self = setmetatable({}, QuestManager)
self.Player = player
self.ActiveQuests = profileData.ActiveQuests or {}
self.CompletedQuests = profileData.CompletedQuests or {}
return self
end
function QuestManager:CanStartQuest(questId)
local data = QuestDatabase[questId]
if not data then return false end
if self.CompletedQuests[questId] or self.ActiveQuests[questId] then return false end
for _, prereqId in ipairs(data.Prerequisites) do
if not self.CompletedQuests[prereqId] then return false end
end
return true
end
function QuestManager:AcceptQuest(questId)
if not self:CanStartQuest(questId) then return false end
self.ActiveQuests[questId] = {
Step = 1,
Counters = table.create(#QuestDatabase[questId].Steps[1].Objectives, 0)
}
return true
end
return QuestManager
3. Olay Veriyolu (Signal Bus) ile Hedef Takibi
Oyun içi eylemleri görev kodundan tamamen ayırma:
- Merkezi Olay Veriyolu: Yaratık ölüm koduna görev yazmak yerine genel bir
EntityKilledsinyali yayılır. - Dinamik Filtreleme: Görev yöneticisi sadece aktif hedeflere uyan sinyalleri dinleyerek işlemciyi yormaz.
- Bileşik Görevler: Hem eşya toplama hem düşman kesme gibi çoklu hedefler tek sayaçta senkronize edilir.
4. Dallanan Diyalog Ağaçları & Karar Mantığı
Oyunun akışını değiştiren etkileşimli NPC konuşmaları:
- Düğüm Tabanlı Diyaloglar: Konuşmalar kamera açıları, metinler ve oyuncu cevap seçenekleriyle birbirine bağlanır.
- Koşullu Seçenekler: Özel cevaplar yalnızca çantada doğru eşya veya yeterli itibar varsa ekranda belirir.
- Diyalog İçi Tetikleyiciler: Eşya verme, ara sahne başlatma veya boss dövüşü açma işlemleri doğrudan diyalogdan yönetilir.
5. ProfileService ile Bitfield Kayıt Sıkıştırması
Yüzlerce tamamlanmış görevi neredeyse sıfır yer kaplayarak kaydetme:
- Bitfield Paketleme: Biten görevler tamsayıların bitlerine kodlanarak 32 görev sadece 4 baytta saklanır.
- Sadece Aktif Durumu Saklama: Veritabanına gereksiz açıklamalar yerine sadece aktif görev ID ve sayaçları yazılır.
- Sürüm Göçü (Migration): Hikaye güncellendiğinde ProfileService sürüm kancaları eski oyuncu verilerini güvenle uyarlar.
Frequently Asked Questions
Görevler neden DAG çizgeleriyle tasarlanmalıdır?
Görevlerin birbirini sonsuz döngüde beklemesini önlemek ve mantıksal önkoşulları hatasız kurmak için.
Olay veriyolu (event bus) performansı nasıl artırır?
Her karede kontrol yapmayı bırakıp sadece ilgili eylem gerçekleştiğinde tetiklenerek CPU kullanımını sıfıra indirir.
Ani bağlantı kopmasında görev kaybı nasıl önlenir?
Oturum kilitlemeli ProfileService kullanarak sayaçları bellekte anında güncelleyip güvenle diske yazarak.
Diyalogdan güvenli ödül nasıl dağıtılır?
Diyalog istemcide oynatılır ancak ödül düğümüne basıldığında sunucu RemoteFunction ile koşulları onaylayıp eşyayı verir.