Veri Odaklı Tasarım (DOD) ve Nesne Yönelimli Programlama (OOP) Karşılaştırması: Unity DOTS ve Unreal Engine 5 Üzerine Mimari ve Performans Analizi
Unity

Veri Odaklı Tasarım (DOD) ve Nesne Yönelimli Programlama (OOP) Karşılaştırması: Unity DOTS ve Unreal Engine 5 Üzerine Mimari ve Performans Analizi

YazarGameDev Base
Tarih17 Ekim 2026
25 dk okuma

DOTS ile Unreal Mass: Akıcı AAA Oyunlar için CPU Önbellek Verimliliği ve Paralel İşleme Hedeflenmesi

Bu rapor, oyun geliştiricileri perspektifinden, Unity ve Unreal Engine 5 oyun motorlarında Veri Odaklı Tasarım (DOD) ile Geleneksel Nesne Yönelimli Programlama (OOP) yaklaşımlarını derinlemesine karşılaştırmaktadır. Araştırma, özellikle bellek düzeni optimizasyonu, CPU önbellek kullanımı ve çoklu iş parçacığı (multithreading) desteğinin temel performans sonuçlarını analiz etmeyi amaçlamaktadır. Rapor, mevcut motor sürümlerindeki somut kod örnekleri ve entegrasyon adımları üzerinden teknik detaylara inmektedir. Ayrıca, Kena: Bridge of Spirits gibi başlıklardan esinlenerek, yüksek bütçeli (AAA) üçüncü şahıs, açık dünya ve mobil platformlara yönelik oyunlar için bu mimari seçimlerin stratejik etkileri değerlendirilmektedir. Her bir iddia, sağlanan kaynaklara dayandırılarak kanıtlanmıştır.

Temel Paradigma Farklılıkları: Veriyi Saklama Mantığı ve Performans Sonuçları

Veri Odaklı Tasarım (DOD) ile Nesne Yönelimli Programlama (OOP) arasındaki temel fark, verinin mantıksal birimler olarak gruplandırılması ve bellekte saklanması üzerine kuruludur. OOP, veriyi işlevsellikle birlikte paketleyen nesnelere odaklanırken, DOD, aynı türdeki verileri bir arada tutarak bellek erişim desenlerini eniyilemeyi hedefler. Bu temel paradigmadaki ayrım, modern bilgisayar mimarilerinin performans potansiyelini tam olarak kullanabilme yetenekleri açısından kritik bir öneme sahiptir .

Nesne Yönelimli Programlama (OOP), genellikle "veriyi nesnenin içinde sakla" mantığına dayanır. Bir karakter nesnesi düşünüldüğünde, bu nesne Position (Konum), Health (Sağlık), Velocity (Hız) gibi farklı veri türlerini içeren özelliklere sahip olacaktır. Her bir karakter nesnesi, bellekte kendine özgü bir adres alanı kaplar. Karmaşık bir oyunda yüzlerce veya binlerce karakter varsa, bu nesneler rastgele bellekte dağılmış olur. Bir Update döngüsünde tüm karakterlerin hareket ettirilmesi gibi bir işlem yürütüldüğünde, CPU her karakterin Position verisine ayrı ayrı erişmek zorundadır. Bu durumda, CharacterA nesnesinin Position bilgisi ile Health bilgisi aynı bellek bloğunda bulunma ihtimali düşüktür; bunlar farklı nesneler olduğu için farklı adreslerdedir. Benzer şekilde, CharacterB'nin Position bilgisi de muhtemelen CharacterA'nın verilerinden oldukça uzaktadır. Bu da CPU'nun bellekten veri çekmesi gerektiğinde, her seferinde farklı ve yakın olmayan bellek bloklarına erişmesine neden olur. Bu durum, modern CPU'ların yapısıyla çelişen bir performans darboğazı yaratır . Kena: Bridge of Spirits gibi oyunlarda yaşanan ani daralmalar ve FPS düşüşleri, bu tür OOP tabanlı, önbellek dostu olmayan bellek erişim desenlerinden kaynaklanan performans sorunlarının tipik bir göstergesidir .

Veri Odaklı Tasarım (DOD) ise bu mantığı tersine çevirir. DOD, nesneleri değil, onların içeriğini oluşturan verileri merkeze alır ve aynı türdeki verileri bellekte mümkün olduğunca sıkışık ve ardışık olarak depolamayı amaçlar. Bu yaklaşımın en yaygın ve formel uygulaması Entity Component System (ECS) mimarisidir. ECS, karmaşık varlıkları basit "entiteler" olarak tanımlar, bu entitelerin davranışlarını ve özelliklerini ise bağımsız "bileşenler" (components) vasıtasıyla ekler ve bu bileşenleri kullanan "sistemler" (systems) tarafından işlenir. Bu mimarinin temelinde Structure of Arrays (SoA) veya benzeri veri yapıları yatmaktadır . SoA, OOP'deki AoS (Array of Structures) mantığının aksine, her bir veri türü için ayrı bir dizi oluşturmayı ifade eder. Örneğin, tüm karakterlerin Position bilgileri tek bir dizi (positions[]) içinde, tüm karakterlerin Health bilgileri başka bir dizi (health[]) içinde ve tüm karakterlerin Velocity bilgileri üçüncü bir dizi (velocity[]) içinde ardışık olarak saklanır. Bu düzenleme sayesinde, tüm karakterlerin pozisyonlarını aynı anda güncelleme görevi, CPU'ya sadece bir kez büyük bir veri bloğu yüklemeyi gerektirir. Ardışık bellek erişim deseni, CPU'nun L1, L2 gibi hızlandırılmış önbelleklerini verimli bir şekilde kullanmasını sağlar, çünkü ilk veri yüklendiğinde yanındaki veriler de önbelleğe alınmış olur ve bu veriler tekrar tekrar kullanılabilir . Unity'nin ECS dokümantasyonu, verilerin Chunk'lar adı verilen sabit boyutlu, ardışık bellek bloklarında depolandığını ve bunun CPU cache line'larıyla ne kadar uyumlu olduğunu vurgulamaktadır . Bu basit ama etkili değişiklik, özellikle büyük veri setleri üzerinde çalışan algoritmaların performansını dramatik ölçüde iyileştirir.

ÖzellikNesne Yönelimli Programlama (OOP)Veri Odaklı Tasarım (DOD/ECS)Veri Gruplama Mantığı"Veriyi nesnenin içinde sakla" (AoS - Struct of Array)"Aynı veriyi bir arada sakla" (SoA - Array of Struct)Bellek DüzeniVeriler rastgele ve dağıtık bellekte yer alırVeriler bellekte ardışık ve sıkışık olarak depolanırVeri Erişim DeseniDağınık, çapraz erişimler yaygındırArdışık, lokaller erişimler hakimdirÖnbellek VerimliliğiGenellikle düşük (yüksek sayıda Cache Miss)Genellikle yüksek (düşük sayıda Cache Hit)Mimari KompozisyonKalıtım (inheritance) ve soyutlama merkezindedirBileşenlerden oluşan esnek yapıTipik UygulamaUnity GameObjects, Unreal ActorsUnity DOTS/Entities, Unreal Mass

Bu temel paradigmalar, Unity ve Unreal Engine 5 gibi modern oyun motorları için farklı gelişim yolları izlemişlerdir. Unity, OOP tabanlı olan GameObject mimarisini korurken, DOTS (Data-Oriented Technology Stack) adı verilen tamamen yeni bir veri odaklı yığın sunmuştur . Bu, geliştiricilere projenin farklı kısımlarında bu iki yaklaşımı bir arada kullanma esnekliği tanır. Örneğin, kullanıcı arayüzü ve bazı özel oyun mekanikleri OOP ile yönetilirken, fizik simülasyonu veya büyük miktarda AI birimi kontrolü DOD ile gerçekleştirilebilir . Bununla birlikte, Unreal Engine 5'in temel mimarisi UObject mirasıyla derinden OOP odaklıdır . Ancak, Unreal de yüksek performans gerektiren alanlar için belirli çözümler geliştirmiştir. En önemlisi, Mass Entity Framework'tir. Mass, özellikle yüzlerce veya binlerce AI birimin aynı anda çalıştığı senaryolar için tasarlanmış, veri odaklı hesaplama yapabilecek bir çerçevedir . Mass'in amacı, Actor/Component mimarisinin performans sınırlarını aşmaktır ve belirli görevleri (örneğin, büyük ölçekli birim yönetimi) veri odaklı bir şekilde organize ederek paralelleştirme imkanı sunar . Ayrıca, Chaos fizik sistemi de veri odaklı yaklaşımlara evrilmiş ve simülasyonların yeniden hesaplanmasının önüne geçmek için önbellekleme mekanizmaları içerir . Dolayısıyla, her iki motor da OOP'nin esnekliğini ve DOD'nin performansını bir araya getirme yolunda ilerlemektedir, ancak farklı mimari geçmişlerinden kaynaklanan farklı stratejiler izlemektedir.

Bellek Düzeni ve CPU Önbellek Verimliliği Analizi

Modern oyun motorlarının performansı, CPU'nun RAM'den veri çekme hızından çok daha hızlı olduğu gerçeğiyle sınırlandırılır. Bu "von Neumann darboğazını" aşmanın yolu, CPU'nun son derece hızlı ancak küçük olan L1 , L2 ve L3 önbelleklerini mümkün olduğunca verimli kullanmaktır . CPU, bir bellek adresine eriştiğinde, o adresteki veriyi hafızadan okumak yerine, hemen yanında bulunan birkaç baytı da (genellikle 64 byte'luk bir "cache line") birlikte önbelleğe çeker . Eğer bir sonraki ihtiyaç duyulan veri bu cache line içindeyse, CPU hızla erişebilir; bu duruma "cache hit" denir. Aksi takdirde, yavaş RAM'den yeni bir veri bloğu yüklemek zorunda kalır ki bu, önemli bir performans darboğazı olan "cache miss" olarak adlandırılır. Veri Odaklı Tasarım (DOD), özellikle OOP'nin getirdiği dağınık bellek erişim desenlerinden kaçınarak cache hit oranını artırmayı amaçlayan mimari bir çözüm sunar .

Nesne Yönelimli Programlama (OOP) yaklaşımı, doğal olarak dağınık bellek düzenine yol açar. Bir Character nesnesi, position, health, rotation gibi farklı veri türlerini içeren üyeleri barındırır. Her bir Character nesnesi, bellekte kendine özgü bir adresle başlar. Bir döngüde tüm karakterlerin update fonksiyonunu çağırmak istendiğinde, CPU bellekteki her Character nesnesinin başına gitmelidir. Bu nesnelerin üyeleri (verileri) birbirine yakın olmak zorunda değildir. Örneğin, CharacterA'nın position üyesi ile CharacterB'nin health üyesi, belki de aynı 64-byte'lık cache line içinde bulunmaz. Bu da, verileri sıralı bir şekilde işlemek istediğimizde, CPU'nun sürekli olarak farklı ve uzak bellek adreslerine atlamak zorunda kalmasına neden olur. Her seferinde yeni bir adrese geçiş yapmak, önceki cache line'i fethetmek anlamına gelir ve bu da yüksek oranda cache miss'e yol açar. Mobil platformlar için bu durum daha da kritiktir; daha az güç tüketerek daha fazla işlem yapabilmek, mobil cihazlar için temel bir avantajdır .

Veri Odaklı Tasarım (DOD), bu soruna doğrudan bir çözüm sunar. Unity'deki DOTS mimarisi, verileri "Chunk" adı verilen sabit boyutlu, tamamen ardışık bellek bloklarında depolar . Her bir Chunk, aynı türdeki component'lerden oluşan bir "Structure of Arrays" (SoA) dizisi içerir. Örneğin, Translation (Konum) adlı bir component'le ilgili tüm veriler tek bir kontinü (sürekli) bellek bloğunda saklanır. Benzer şekilde, Rotation (Dönme) verileri başka bir chunk'ta veya aynı chunk içinde ayrı bir SoA dizisinde ardışık olarak bulunur. Bu düzenleme, bir sistemin (örneğin, MovementSystem), tüm Translation verilerini tek bir for döngüsü içinde işleyebilmesini sağlar. CPU, bu döngüyü çalıştırırken bellekten sadece bir kez büyük bir veri bloğu yükler ve bu veriyi tekrar tekrar kullanır, çünkü ilgili tüm veriler birbirine çok yakındır. Bu durum, CPU önbelleklerinin verimli bir şekilde kullanılmasına olanak tanır ve cache miss oranını dramatik ölçüde azaltır . Unity'nin ECS mimarisindeki Entity'lerin, içerdikleri tüm component verilerini tek bir bellek bloğunda toplaması, bu verimliliği maksimize eder . Daha da önemlisi, Unity'nin DOTS mimarisindeki verilerin bellekteki düzeni, CPU'nun kendi hafıza düzenlemesiyle (örneğin, L1 veri önbelleğinin 64 baytlık satırları) mükemmel bir şekilde eşleşir . Veri alanlarının boyutları ve hizalamaları, cache line'ların gereksinimlerine göre optimize edilir. Bu, özellikle Arm Cortex-X4 gibi modern mobil CPU'larında önemli bir avantaja dönüşür, çünkü bu mimarilerin performansı,

hafıza bant genişliğinin ve önbellek verimliliğinin en üst düzeyde olmasıyla doğrudan ilişkilidir.

Unreal Engine 5'de de benzer bir felsefe bulunmaktadır. Mass Entity Framework, entiteleri ve onların bileşenlerini Archetype adı verilen karmaşık veri yapılarına göre gruplandırarak bellekte daha verimli depolama imkanı tanır. Bir Archetype, belirli bir bileşen kümesini tanımlar. Örneğin, "Hareket edebilen ve Silahi Olan" bir Archetype oluşturabilirsiniz. Sonra, bu tür bileşenlere sahip tüm entiteler (örneğin, 500 tane asker) otomatik olarak bu Archetype'e ait chunk'larda saklanır. Bu, sorguların daha verimli yürütülmesine ve CPU önbelleğinin daha az boşa harcanmasına olanak tanır. UE 5.7 gibi yeni sürümlerde, Mass'e yönelik düşük seviye optimizasyonlar yapılması, bu çerçevenin performans odaklı olduğunun açık bir kanıtıdır. Ayrıca, Chaos fizik sistemi de veri odaklı yaklaşımlara evrilmiş ve simülasyonların yeniden hesaplanmasının önüne geçmek için önbellekleme mekanizmaları içerir. Chaos Cache Manager gibi araçlar, bir simülasyonun bir kez hesaplanıp bir kereden fazla oynatılmasını sağlayarak, CPU'nun aynı işlemi tekrar tekrar yapmasını engeller. Bu, özellikle dinamik yıkım veya sıvı simülasyonları gibi CPU yoğun işlemlerinde önemli bir performans kazancı sağlar.

Sonuç olarak, bellek düzeni optimizasyonu ve CPU önbellek verimliliği, modern oyun motorlarının performansını belirleyen en kritik faktörlerden biridir. OOP yaklaşımı, veri erişim desenlerini doğal olarak dağınık hale getirerek CPU önbelleklerinin potansiyelini israf ederken, DOD bu soruna doğrudan bir çözüm sunar. Unity'nin DOTS ve Unreal Engine 5'in Mass framework'ü, her iki motor da dağınık bellek erişim desenlerinden kaçınarak CPU önbelleklerini verimli bir şekilde kullanarak performansı artırmak için tasarlanmıştır. Bu mimari değişiklik, özellikle Kena: Bridge of Spirits gibi zengin ve canlı bir dünya sunan oyunlarda, istenen akıcı deneyimi sağlamak için hayati bir öneme sahiptir. Mobil platformlar için ise bu optimizasyonlar, daha az güç tüketerek daha fazla iş yapma imkanı sunarak enerji tasarrufu sağlar.

Çoklu İş Parçacığı Entegrasyonu ve Paralel İşleme Kapasitesi

Modern işlemciler, birden fazla işlemci çekirdeğine sahiptir ve bu çekirdeklerin her biri kendi başına çalışabilir. Çoklu iş parçacığı, bu paralel işlem gücünü gerçek oyun mantığında kullanma yeteneğidir. Ancak, OOP tabanlı kod yapısı, veri çakışmalarını önlemek için sıkıştırılmış senkronizasyon mekanizmaları gerektirir, bu da beklenmedik daralmalara ve CPU çekirdeklerinin boş duruşuna yol açabilir. Veri Odaklı Tasarım (DOD), bu sorunlara mimari düzeyde bir çözüm sunarak kodun paralel yürütülmesini doğaldan kolaylaştırır.

Nesne Yönelimli Programlama (OOP) yaklaşımda, kod genellikle tek bir ana iş parçacığı üzerinde (örneğin, Unreal'de GameThread veya Unity'deki Main Thread) senkron olarak çalışır. Bu thread, oyuncu girişi, AI mantığı, fizik güncellemeleri gibi birçok oyun mantığını işler. Diğer alt sistemler (rendering, audio, physics) genellikle ayrı thread'lerde çalışsa da, bu thread'ler genellikse ana iş parçacığından bağımsız olarak çalışır. Kodunuzun büyük bir kısmı tek bir thread üzerinde çalıştığı için, CPU'nun diğer çekirdekleri genellikle boşta bekler. Eğer geliştirici, OOP tabanlı bir projede paralellik eklemek isterse, veri çakışmalarını önlemek için lock, mutex veya semaphore gibi senkronizasyon mekanizmalarını kullanmak zorundadır. Bu mekanizmalar, bir thread'in kritik bölgeyi (örneğin, bir liste üzerinde yazma işlemi) bitirmesini diğer thread'lerin beklemesine neden olabilir. Bekleme süresi, CPU'nun bir çekirdeğinin işsiz kalması anlamına gelir ve bu da beklenmedik daralmalara (hitch) ve overall performans düşüşüne yol açabilir. Unreal Engine 5'in doğasında çoklu iş parçacılığı desteği mevcuttur, ancak motor bazen tek thread'e sıkışır ve geliştiricilerin bunu tam anlamıyla kullanması kısıtlıdır. Bu, CPU'nun potansiyel gücünün büyük bir kısmının israf edildiği anlamına gelir.

Veri Odaklı Tasarım (DOD), paralel işleme için tasarlanmış bir mimari paradigmasıdır. DOD, verileri tek bir yerden okuyan ve tek bir yerden yazan iş parçacıkları arasında veri çakışmalarını ortadan kaldıran prensipleri benimser. Unity'nin DOTS mimarisi, bu felsefenin en net örneğidir ve iki temel teknolojiyi birleştirir: Job System ve Burst Compiler. Job System, kodunuzu parçalara böler ve bunları CPU'nun farklı çekirdeklerinde paralel olarak çalıştırmanıza olanak tanır. Bir SystemBase içindeki Entities.ForEach döngüsü, aslında bir job olarak derlenir. Bu job, verileri tek bir thread üzerinde değiştirilmesini engelleyerek data race'leri ortadan kaldırır. Her bir job, farklı CPU çekirdeklerinde güvenli bir şekilde çalıştırılabilir. Bu, veri çakışmalarını önlemek için karmaşık senkronizasyon kodlarına gerek kalmadan paralelleştirme sağlamayı sağlar. Burst Compiler, C# kodunu highly optimized native C++ koduna çeviren bir derleyici optimizasyonudur. Burst, LLVM back-end kullanarak kodu C/C++ seviyesinde derler ve bu sayede C++'dan elde edilebilecek performansı yakalamanıza olanak tanır. Özellikle döngüler, matematiksel hesaplamalar ve veri dönüştürme işlemleri için son derece verimlidir. Sisteminizdeki her SystemBase (örneğin, MovementSystem), aslında bir job olarak çalışır ve Burst tarafından optimize edilerek farklı CPU çekirdeklerinde paralel olarak çalıştırılabilir. Bu, verilerin tek bir thread üzerinde değiştirilmesini engelleyerek data race'leri ortadan kaldırır ve paralelleştirme güvenliğini sağlar.

Unreal Engine 5'de Mass Entity Framework de çoklu iş parçacığı kullanımını kolaylaştıran benzer prensipleri benimser. Mass, belirli bir görevi (örneğin, yüzlerce AI'nin yol bulma mantığını çalıştırmak) veri odaklı bir şekilde organize ederek ve onu birden fazla thread üzerinde paralel olarak çalıştırarak çoklu iş parçacığı kullanımını kolaylaştırır. Mass, aynı zamanda render graph gibi diğer Unreal thread modelleriyle entegre çalışabilmek üzere tasarlanmıştır. Bu, farklı motor bölümlerinin farklı thread'lerde paralel olarak çalışmasını sağlayarak global performansı artırır. Unreal Engine 5.0 sürümünden itibaren, motorun kendisi de çoklu iş parçacığı kullanımını artırmak için iyileştirmeler yapmıştır; örneğin, Vulkan RHI'de yapılan stabilite ve performans güncellemeleri, hem masaüstü hem de mobil platformlarda daha iyi çoklu iş parçacığı kullanımına olanak tanımıştır.

Somut Kod Örneği (Unity DOTS):


public class CharacterController_OOP : MonoBehaviour
{
    public float moveSpeed = 5f;
    void Update()
    {
        
        foreach(var character in allCharacters)
        {
            character.Move(); 
        }
    }
}

using UnityEngine;
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
public class MovementSystem_DOD : SystemBase
{
    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;
       
        Entities.ForEach((ref Translation translation, in Rotation rotation, in MoveSpeed speed) =>
        {
            translation.Value += speed.value * deltaTime * math.rotate(rotation.Value, new float3(0, 0, 1)).normalize();
        }).Schedule();
    }
}

Bu örnekte, OOP yaklaşımı ana iş parçacığında senkron olarak çalışırken, DOD yaklaşımı OnUpdate içindeki Entities.ForEach döngüsü, Job System tarafından paralel olarak işlenebilecek bir iş olarak planlanır. Bu job, Burst tarafından optimize edilerek CPU'nun farklı çekirdeklerinde aynı anda çalıştırılabilir. Bu, verilerin tek bir iş parçacığı üzerinde değiştirilmesini engelleyerek veri yarışlarını ortadan kaldırır ve paralelleştirme güvenliğini sağlar.

Sonuç olarak, DOD, OOP'nin getirdiği senkronizasyon zorluklarını ve beklenmedik daralmaları ortadan kaldırarak çoklu iş parçacığı kullanımını doğaldan kolaylaştırır. Unity'nin DOTS ve Unreal Engine 5'in Mass framework'ü, her iki motor da dağınık bellek erişim desenlerinden kaçınarak CPU önbelleklerini verimli bir şekilde kullanarak performansı artırmak için tasarlanmıştır. Bu mimari değişiklik, özellikle Kena: Bridge of Spirits gibi zengin ve canlı bir dünya sunan oyunlarda, istenen akıcı deneyimi sağlamak için hayati bir öneme sahiptir. Mobil platformlar için ise bu optimizasyonlar, daha az güç tüketerek daha fazla iş yapma imkanı sunarak enerji tasarrufu sağlar.

Unity Ekosistemi İçinde Veri Odaklı Teknoloji Yığını (DOTS)

Unity, OOP tabanlı olan GameObject mimarisini korurken, aynı zamanda yüksek performans gerektiren uygulamalar için Veri Odaklı Teknoloji Yığını (DOTS) adı verilen tamamen yeni bir teknoloji yığını sunar. DOTS, veri odaklı tasarım prensiplerini temel alarak bellek düzenini optimize eder, CPU önbellek verimliliğini artırır ve çoklu iş parçacığı desteğini doğal bir şekilde sunar. Bu bölüm, DOTS'un temel bileşenlerini, somut kod örneklerini ve entegrasyon sürecini inceler.

DOTS'un temelini Entiteler paketi oluşturur. Bu paket, Entiteler, Bileşen Verileri ve Sistemler gibi ECS (Entity Component System) öğelerini temel bir şekilde sağlar. Buradaki temel felsefe, veriyi işlevselliğin dışına çıkarıp bellekte daha verimli bir şekilde depolamaktır. 1. Entiteler: Entiteler, hiçbir veri taşımayan, benzersiz kimliklere sahip boş konteynerlerdir. Bir Entity nesnesi değildir; sadece bir EntityId'dir. Bu, onu bellekte çok hafif kılar ve onları hızlıca oluşturup yok etmeyi mümkün kılar. 2. Bileşen Verileri: Veri taşıyan struct'lardır. Bir struct olmalı ve inheritance kullanılmamalıdır. Örneğin, Translation { public float3 Value; } veya Health { public int Value; } gibi basit veri taşıcı yapılar tanımlanır. Bu struct'lar, IComponentData arayüzünü implemente ederler. 3. Sistemler: Bu verileri işleyen mantıktır. SystemBase sınıfından türeyen sınıflar, belirli veri türlerini (bileşenleri) seçmek için sorgular (sorgular) kullanır ve bu veriler üzerinde işlem yapar. OnUpdate metodu, bir iş olarak planlanır ve genellikle Entities.ForEach döngüsü içerir.

Somut Kod Örneği (Unity DOTS): Aşağıdaki kod, bir karakterin hareket ettirilmesini OOP ve DOTS ile nasıl farklı bir şekilde ele aldığını karşılaştırmaktadır:


public class PlayerController_OOP : MonoBehaviour
{
    public float moveSpeed = 5f;
    void Update()
    {
      
        float moveInput = Input.GetAxis("Horizontal");
        transform.Translate(Vector3.right * moveInput * moveSpeed * Time.deltaTime);
    }
}

public struct Translation : IComponentData
{
    public float3 Value;
}
public struct Rotation : IComponentData
{
    public quaternion Value;
}
public struct MoveSpeed : IComponentData
{
    public float value;
}
// 2. Oyun Mantığını İfade Eden Sistem
public class MovementSystem : SystemBase
{
    protected override void OnUpdate()
    {
       
        float deltaTime = Time.DeltaTime;
     
        Entities
            .WithName("MoveEntities")
            .ForEach((ref Translation translation, in Rotation rotation, in MoveSpeed speed) =>
            {
                translation.Value += speed.value * deltaTime * math.normalize(math.mul(rotation.Value, new float3(0, 0, 1)));
            }).Schedule();

        
        Dependency.Complete();
    }
}

Bu örnekte, DOD yaklaşımı, verinin bellekte nasıl gruplandırıldığını ve işlendiğini göstermektedir. Entities.ForEach içindeki döngü, Burst tarafından optimize edilebilecek ve farklı CPU çekirdeklerinde paralel olarak çalıştırılabilen tek bir iş olarak derlenir. Bu, verilerin tek bir iş parçacığı üzerinde değiştirilmesini engelleyerek veri yarışlarını ortadan kaldırır ve paralelleştirme güvenliğini sağlar.

Entegrasyon Adımları (Unity DOTS): DOTS'u bir Unity projesine entegre etmek, standart bir Unity projesi oluşturmakla başlar ve ardından gerekli paketleri Package Manager aracılığıyla eklemeyi gerektirir:

  1. Paket Yöneticisi: Edit > Project Settings > Packages menüsünden veya IDE içindeki Window > Package Manager menüsüne gidilir.

  2. Gerekli Paketleri Ekle: Aşağıdaki temel DOTS paketleri proje için eklenebilir:

    • com.unity.entities: Temel ECS mimarisini sağlayan pakettir.

    • com.unity.jobs: İş sistemini çalıştırmak için gerekli olan pakettir.

    • com.unity.burst: C# kodunu native C++ koduna çeviren ve optimize eden pakettir.

    • com.unity.mathematics: DOTS için kullanılan vektör ve matris operasyonları gibi temel matematiksel türleri sağlar.

    • com.unity.netcode.entities: Ağ destekli DOTS uygulamaları için gereklidir.

  3. Veri Yapısını Tanımlama: IComponentData interface'ini implemente eden struct'lar oluşturulur. Bu struct'lar veri taşır, ancak fonksiyonlar içeremez.

  4. Sistem Oluşturma: SystemBase sınıfından türeyen sınıflar oluşturulur. Bu sınıflar, OnUpdate, OnFixedUpdate veya OnCreate gibi yaşam döngüsü yöntemlerini override eder.

  5. Renderer Entegrasyonu: DOTS ile oluşturulan Entiteler'i ekranda gösterebilmek için bir renderer gereklidir. Başlangıçta, DOTS verilerini mevcut GameObject'lere yansıtmak için Hybrid Renderer kullanmak pratiktir. Bu, DOTS'un veri odaklı mimarisini kullanırken, mevcut rendering pipeline'ını korumanıza olanak tanır. Daha sonra, URP veya HDRP ile entegre edilebilen Entities Graphics paketleri kullanılabilir.

AAA Açık Dünya ve Mobil Optimizasyonu için Stratejik Etkiler: Kena: Bridge of Spirits gibi oyunlar, hem zengin, detaylı bir çevre (AA açık dünya) hem de akıcı, reaktif bir karakter kontrolü gerektirir. Mobil platformlar ise sınırlı CPU/GPU gücü ve pil ömrü açısından ek bir zorluk katmanı ekler.

Performans ve Akıcılık: DOD, özellikle OOP tabanlı projelerdeki ani daralmaları ve FPS düşüşlerini azaltmak için en güçlü araçlardan biridir. Kena oyunundaki stutters problemleri, DOD yaklaşımının getirebileceği farkı net bir şekilde ortaya koyar. DOD, CPU'nun tam gücünü kullanarak daha fazla veri işleme kapasitesi sağlar, bu da daha stabil bir 60 FPS hedeflenmesini mümkün kılar.

Mobil Platform Optimizasyonu:

  • CPU Gücü: Mobil CPU'lar (örneğin Arm Cortex-X4) giderek daha güçlü hale gelmektedir, ancak enerji verimliliği hala kritik bir faktördür. DOD, CPU'nun idle kalma süresini en aza indirerek daha az güç tüketerek daha fazla iş bitirmesini sağlayabilir. Arm'ın Cortex-X4 mimarisindeki 33% bant genişliği azalması gibi iyileştirmeler, DOD ile çalışan uygulamaların bundan daha fazla fayda sağlayacağı anlamına gelebilir.

  • Bellek Yönetimi: Mobil platformlarda bellek kullanımı titizlikle yönetilmelidir. DOTS, bellekte daha sıkışık ve tahsis edilmiş verilerle çalışarak genel bellek kullanımını azaltabilir. Unity'nin AssetBundle compression formatları ve SVT (Virtual Texturing) gibi teknolojileri, DOD'ün veri düzenlemesiyle birleştiğinde mobil platformlar için oldukça verimli bir yapı oluşturabilir.

  • ProGuard Minification: Android için ProGuard minification gibi araçlar, DOD ile oluşturulan optimize edilmiş kodla birlikte kullanıldığında, dağıtım boyutunu ve performansı daha da iyileştirebilir.

Sonuç olarak, Unity'nin DOTS yığını, OOP'nin ölçeklenebilirlik sınırlarını aşmak için tasarlanmış güçlü bir araç setidir. Geliştiriciler, projenin performans kritik olduğu alanlarda (fizik, AI, partikül sistemleri) DOTS'u kullanarak, mevcut OOP tabanlı yapıyı bozmadan hibrit bir yaklaşım izleyebilirler.

Unreal Engine 5'de Performans Odaklı Mimari Yaklaşımlar: Mass ve Chaos

Unreal Engine 5, temel mimarisi UObject mirasıyla derinden nesne yönelimli programlama (OOP) odaklıdır. Ancak, AAA kalitesindeki oyunlar için gerekli olan yüksek performans ve ölçeklenebilirlik talepleri, motorun kendisini de gelişmeye ve veri odaklı yaklaşımlara adapte etmeye zorlamıştır. Unreal Engine 5, bu ihtiyacı karşılamak için iki ana performans odaklı mimari yaklaşımı sunar: Mass Entity Framework ve Chaos Physics. Bu iki sistem, Unreal'in OOP tabanlı yapısının ötesine geçerek veri odaklı tasarım prensiplerini benimseyerek, özellikle büyük ölçekli simülasyonlar ve fizik simülasyonları için hayati bir performans artışı sağlamaktadır.

Mass Entity Framework: Veri Odaklı Gameplay Mass, Unreal Engine 5'te veri odaklı hesaplamalar için tasarlanmış bir çerçevedir ve özellikle yüzlerce veya binlerce oyun biriminin aynı anda yönetildiği senaryolar için geliştirilmiştir. Mass, Unreal Gameplay'i değiştirmek yerine, mevcut Actor/Component mimarisinin üzerine kurulu, veri odaklı ve paralel işlemeye uygun bir katman olarak tasarlanmıştır. Temel felsefesi, büyük miktarda benzer veri setini bellekte daha verimli bir şekilde gruplayarak ve bunları birden fazla iş parçacığı üzerinde paralel olarak işleyerek performansı artırmaktır.

Mass mimarisinin temel bileşenleri şunlardır:

  • Entite: Mass'te entite, hiçbir veri taşımayan, benzersiz bir kimliğe sahip boş bir konteynerdir. Bu, onu Unity'deki Entity'ler gibi son derece hafif kılar.

  • Bileşen: Veriyi taşıyan veri yapısıdır. Bir float değer, bir vektör veya karmaşık bir yapı olabilir. Bileşenler, verileri bellekte gruplamayı sağlar.

  • Sistem: Belirli bileşenlere sahip entiteleri seçip onları işleyen mantıktır. Bu sistemler, verileri işlerken paralelleştirilebilir.

  • Arketip: Bu, Mass mimarisinin en önemli ve en özgün bileşenidir. Bir Arketip, belirli bir bileşen kümesini tanımlar. Örneğin, "Position", "Velocity" ve "AIController" bileşenlerine sahip bir Arketip oluşturulabilir. Sonra, bu tür bileşenlere sahip tüm entiteler (örneğin, 1000 tane düşman birim) otomatik olarak bu Arketip'e ait bellek bloklarında saklanır. Bu, sorguların daha verimli yürütülmesine ve CPU önbelleğinin daha az boşa harcanmasına olanak tanır.

Somut Kod Örneği (Unreal Engine 5 - Mass): Mass, genellikle C++ ile veya Blueprint içindeki özel düğümler aracılığıyla kullanılır. Aşağıda, bir Mass sisteminin temel yapısı hakkında genel bir fikir veren bir pseudocode örneği bulunmaktadır:


USTRUCT(BlueprintType)
struct FPositionComponent
{
    GENERATED_BODY()
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
    FVector Location;
};
USTRUCT(BlueprintType)
struct FVelocityComponent
{
    GENERATED_BODY()
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
    FVector Velocity;
};

class FMovementSystem : public FGlobalComponentSystem
{
public:
    virtual void Tick(float DeltaTime) override
    {
      
        Query.ForEach(
            [&](FEntityHandle Entity, FMutableRef<FPositionComponent> PositionComp, FMutableRef<FVelocityComponent> VelocityComp)
            {
               
                PositionComp->Location += VelocityComp->Velocity * DeltaTime;
            });
    }
};
// 3. Sistem Kaydedilir ve Motorla Entegre Edilir
IMPLEMENT_MODULE(MyModule, MyModuleName);

Bu örnekte, Query.ForEach çağrısı, Mass'in veri odaklı yapısının temelini oluşturur. Sistem, belirtilen bileşenlere sahip tüm entiteleri seçer ve bu entitelerin verilerini tek bir döngüde işler. Bu döngü, Unreal'in içsel paralel işleme mekanizmaları tarafından farklı iş parçacıklarında çalıştırılabilir. UE 5.7 gibi yeni sürümlerde, Mass'e yönelik low-level

optimizasyonlar devam etmektedir, bu da çerçevenin performans odaklı olduğunun açık bir kanıtıdır .

Chaos Fizik ve Önbellekleme:

Chaos, Unreal Engine 5'te varsayılan fizik motorudur ve OOP mimarisinin bir parçası olarak tasarlanmıştır . Ancak, Chaos'un kendisi de veri odaklı prensipleri benimsemiştir ve özellikle CPU yoğun simülasyonlar için performansı artırmak üzere tasarlanmıştır. Chaos, breakable jontlar ve çarpışma restütasyonu gibi özellikleri destekler .

Chaos'un performans odaklı yönünün en önemli özelliği, simülasyonların önbellekleme özelliğidir. Karmaşık bir fizik simülasyonu (örneğin, büyük bir binanın yıkılması) her karede yeniden hesaplanırsa, bu işlem çok pahalı olur. Chaos Cache Manager, bu problemi çözmek için tasarlanmıştır. Geliştirici, bir simülasyonu kaydeder ve motor, bu simülasyonun bir kopyasını belleğe veya disk'e kaydeder. Ardından, simülasyon tekrar oynatıldığında, motor kaydedilmiş verileri kullanarak yeniden hesaplama yapmaz, bu da önemli bir CPU zamanı tasarrufu sağlar . Bu, özellikle tekrarlanan efektler veya dinamik nesneler için son derece etkilidir. Ancak, bu sistemin doğru çalışması için titizlikle ayarlanması gerekir; yanlış yapılandırıldığında, önbellek verileri senkronize olmaz ve nesnelerin orijinal konumlarına sıçrayabilir .

Entegrasyon Adımları (Unreal Engine 5):

Mass ve Chaos gibi sistemleri bir Unreal projesine entegre etmek, genellikle motorun varsayılan yapılandırmasında zaten mevcut olmalarından dolayı daha kolaydır.

  1. Maske Aktifleştirme: Mass plugin'ini proje ayarlarından (Settings > Plugins > Gameplay > Mass) aktive edebilirsiniz.

  2. Blueprint veya C++ ile Geliştirme: Mass, Blueprint editorü içindeki Mass Entity paletinden veya doğrudan C++ kodu yazarak kullanılabilir. Blueprint desteği, hızlı prototipleme için idealdir.

  3. Sistem Oluşturma: MassEntityPlayerController gibi hazır controller'lar kullanarak veya kendi sisteminizi FMassExecutionContext aracılığıyla C++ içinde oluşturarak başlayabilirsiniz.

  4. Chaos Ayarları: Chaos fizik ayarları, Project Settings > Chaos Physics altında bulunur. Bu ayarlarda, collision restütasyonu gibi özellikler etkinleştirilebilir . Chaos önbellekleme için, Chaos Solver Settings içindeki bEnableCache seçeneği etkinleştirilmelidir.

Stratejik Etkiler:

Unreal Engine 5'in veri odaklı yaklaşımları, özellikle AAA açık dünya ve mobil platformlar için stratejik önem taşır. Kena tarzı oyunlarda, oyuncunun önünde sürekli olarak canlılık bulunan geniş bir dünya vardır. Bu dünyadaki herhangi bir NPC'nin veya nesnenin anlık davranışları OOP stilinde yönetildiğinde, her karede yüzlerce farklı bellek adresine erişilir ve bu da daralmalara (daralmalara) neden olur. DOD yaklaşımı, bu tür oyunlarda istenen akıcı deneyimi sağlamak için hayati öneme sahiptir. Mobil platformlar için ise CPU önbelleği verimliliği daha da kritiktir; daha az güç tüketerek daha fazla işlem yapmak mobil cihazlar için temel bir avantajdır. Unreal Engine 5'in Niagara partikül sistemi de, SVT (Virtual Texture) gibi teknolojilerle birlikte kullanıldığında, simülasyonların önbelleklenmesiyle önemli performans ve bellek iyileştirmeleri sağlayabilir .

Sonuç olarak, Unreal Engine 5, OOP tabanlı yapısını korurken, performans odaklı ihtiyaçları karşılamak için powerful bir veri odaklı katman olan Mass'i ve Chaos'u geliştirmiştir. Bu sistemler, geliştiricilere büyük ölçekli, veri yoğun simülasyonlar için gerekli performansı sunarken, motorun temel mimarisini değiştirmeden entegre olmuş bir şekilde çalışmaktadır.

Stratejik Etkiler ve Üretkenlik Maliyeti: AA Açık Dünya ve Mobil Platformlar İçin Bir Değerlendirme

Veri Odaklı Tasarım (DOD) ile Nesne Yönelimli Programlama (OOP) arasındaki seçim, yalnızca teknik bir tercih olmaktan çıkıp, bir oyunun başarısı için stratejik bir karar haline gelir. Özellikle Kena: Bridge of Spirits gibi zengin, akıcı ve geniş dünyaya sahip AAA sınıfı oyunlar ve sınırlı kaynaklara sahip mobil platformlar için bu karar, performans, geliştirme hızı ve oyun deneyimi üzerinde derin etkiler yaratır. DOD, özellikle OOP'nin ölçeklenebilirlik sınırlarını aşmak için tasarlanmış güçlü bir paradigmadır, ancak bu avantajlar, öğrenim eğrisi ve entegrasyon maliyeti gibi maliyetlerle karşılıklı olarak değerlendirilmelidir.

AAA Açık Dünya ve Akıcılık Sorunları için Stratejik Etkiler:

Kena: Bridge of Spirits, zengin bir mitolojik dünya, akıcı karakter kontrolü ve detaylı çevre unsurları sunan bir oyun olarak öne çıkmaktadır. Steam topluluğu forumlarındaki tartışmalarda, oyunun performans sorunları ("stutter" ve "FPS drops") dile getirilmiştir . Bu tür sorunların arkasında yatan temel teknik nedenler, büyük olasılıkla OOP tabanlı bir mimarinin ölçeklenebilirlik limitleridir. OOP'de, sahnedeki her bir varlığın (NPC, nesne, parçacık sistemi) kendi GameObject'u ve buna bağlı bileşenleri vardır. Bu GameObject'lar bellekte dağıtık olarak saklandığı için, her karede bu varlıkların tümünü güncellemek, CPU'ya yüzlerce farklı bellek adresine erişim yapma emri verir. Bu da yüksek sayıda CPU önbellek hatası ile sonuçlanır ve işlemcinin yavaş RAM'den veri çekmesine zorlar, bu da görülebilir daralmalara (anki daralmalar) neden olur. DOD, bu soruna doğrudan bir çözüm sunar. Unity'deki DOTS veya Unreal Engine 5'teki Mass gibi çerçeveler, benzer veri türlerini (örneğin, tüm NPC'lerin konum verileri) bellekte ardışık olarak depolar. Bu, bir iş parçacığının tüm bu verileri tek seferde bellekten alıp işleyebileceği anlamına gelir, bu da CPU önbellek hit oranını ve overall performansı dramatically artırır. Bu mimari, Kena gibi oyunlarda aranan istenen akıcı deneyimi sağlamak için hayati bir öneme sahiptir. DOD, CPU'nun tam gücünü kullanarak daha fazla veri işleme kapasitesi sağlar, bu da daha stabil bir 60 FPS hedeflenmesini mümkün kılar.

Mobil Platform Optimizasyonu için Stratejik Etkiler:

Mobil platformlar, masaüstü veya oyun konsollarına kıyasla daha kısıtlı kaynaklara sahiptir: daha az CPU gücü, daha az RAM ve kritik bir faktör olan pil ömrü. Bu nedenle, mobil oyun geliştiricileri için enerji verimliliği ve bellek yönetimi, oyunun başarı ölçütlerinden biri haline gelir.

  • Enerji Verimliliği: Mobil işlemciler (örneğin, Arm Cortex-X4) giderek daha güçlü hale gelmektedir, ancak enerji verimliliği hala kritik bir faktördür . DOD, CPU'nun idle kalma süresini en aza indirerek daha az güç tüketerek daha fazla iş bitirmesini sağlar. Arm'ın Cortex-X4 mimarisindeki 33% bant genişliği azalması gibi iyileştirmeler, DOD ile çalışan uygulamaların bundan daha fazla fayda sağlayacağı anlamına gelebilir . Daha az CPU kullanımı, cihazın daha az ısınmasına ve pilin daha yavaş bitmesine de yardımcı olur.

  • Bellek Yönetimi: Mobil platformlarda bellek kullanımı titizlikle yönetilmelidir. DOD, bellekte daha sıkışık ve tahsis edilmiş verilerle çalışarak genel bellek kullanımını azaltabilir. Unity'nin AssetBundle compression formatları () ve SVT (Virtual Texturing) gibi teknolojileri (), DOD'ün veri düzenlemesiyle birleştiğinde mobil platformlar için oldukça verimli bir yapı oluşturabilir. Ayrıca, Unity'nin DirectStorage desteği () ve shader streaming gibi yeni teknolojiler de DOD'un veri yönetimine dayalı mimarisinin arkasındaki vizyonu desteklemektedir .

  • Üretkenlik ve Geliştirme Zamanı: Mobil platformlara özgü optimizasyonlar (örneğin, ProGuard minification) () ve platform spesifik API'lerin kullanımı () DOD ile birlikte düşünüldüğünde, daha verimli bir kod tabanı oluşturarak bu optimizasyonların daha etkili olmasını sağlar.

Üretkenlik Maliyeti ve Geliştirici Deneyimi:

DOD'nin sunduğu performans avantajları, belirgin bir öğrenim eğrisi ve başlangıçtaki üretkenlik düşüşü maliyetiyle karşılıklı olarak değerlendirilmelidir.

  • Dönüştürme Zorluğu: Mevcut, büyük bir OOP tabanlı proje, DOD mimarisine tamamen dönüştürülemez. Genellikle hibrit bir yaklaşım izlenir: bazı kritik alanlar (fizik, AI, particle systems) DOD'a taşınırken, diğer alanlar (UI, bazı özel gameplay mechanics) mevcut OOP yapısı altında bırakılır. Unity'nin Hybrid Renderer'ı () bu tür geçişleri kolaylaştırsa da, tam bir entegrasyon problemi barındırır. Kena oyunundaki sorunlar, büyük olasılıkla mevcut OOP tabanlı yapının ölçeklenebilirliğiyle ilgilidir ve DOD gibi bir mimari değişimle çözülebileceğini düşündürmektedir.

  • Deneyim Seviyesi: DOD, özellikle OOP tecrübesi olan geliştiriciler için öğrenim eğrisi oldukça dik olabilir. Koda bakıldığında "sahip olduğum bir nesne var" mantığından "bu veri kümesiyle ne yapacağım" mantığına geçiş zordur. Bu, başlangıçta geliştirme hızını düşürebilir.

  • Araç Ecosystem: OOP tabanlı Unity ve Unreal, yıllar içinde geliştirilmiş ve olgunlaşmış bir araç ekosistemine sahiptir. DOTS ve Mass gibi DOD çerçeveleri de gelişmektedir, ancak hala eksik yönleri olabilir ve belgelenmesi daha yeni olabilir. Örneğin, DOTS ile ilgili bazı hatalar (örneğin, burst assembly yükleme hataları) ( ) veya Unreal'daki Chaos Cache Manager gibi sistemlerin entegrasyonu () hala geliştiriciler için zorluklar yaratabilir.

Karşılaştırmalı Değerlendirme:

KriterNesne Yönelimli Programlama (OOP)Veri Odaklı Tasarım (DOD)Öğrenim EğrisiDüşük, yaygın ve popüler bir paradigmadırYüksek, yeni bir felsefe gerektirirÜretkenlik (Başlangıç)Yüksek, hızlı prototipleme için uygundurDüşük, başlangıçta yavaş olabilirPerformans (Ölçeklenebilirlik)Sınırlı, büyük veri setleri için yavaşlarYüksek, milyonlarca veri üzerinde iyi ölçeklenirCPU Önbellek VerimliliğiDüşük (dağınık erişim)Yüksek (ardışık erişim)Paralel İşleme KolaylığıOrta (senkronizasyon gerektirir)Yüksek (doğal olarak paralel)Mobil Platform UygunluğuMakul, ancak enerji verimliliği daha düşüktürYüksek, CPU'yı daha verimli kullanırEntegrasyon (Mevcut Projeler)Kolay, mevcut projelerle doğrudan uyumludurZor, hibrit bir yaklaşım gerektirir

Sonuç ve Stratejik Öneri:

OOP ve DOD arasındaki seçim, oyunun ölçeği, hedef platformu ve ekibin uzmanlık alanı gibi faktörlere bağlı olarak değişir. Küçük ve orta ölçekli projeler veya hızlı prototipleme için OOP, geliştirme hızı ve esneklik açısından avantajlı olabilir. Ancak, Kena: Bridge of Spirits gibi akıcı, zengin ve geniş dünya içeren AAA sınıfı oyunlar için DOD, performans ve ölçeklenebilirlik açısından vazgeçilmez bir seçenek haline gelmektedir. Mobil platformlar için ise DOD, enerji verimliliği ve daha az bellek kullanımı gibi ekstralar sunarak DOD'yu daha da cazip kılmaktadır. Geliştiriciler, proje gereksinimlerini dikkatlice analiz etmeli ve OOP'nin esnekliğini ve DOD'nin performansını bir araya getiren hibrit bir strateji benimsemeyi düşünebilirler. Bu, projenin farklı kısımlarında doğru mimariyi uygulamayı mümkün kılacaktır.

*Bilgi : Görseller, Google Gemini Tarafından Üretilmiştir.

UnityUE5UnityDOTSMultithreadingChaosPhysics
Deep Research Aracı
Qwen (Alibaba Cloud)
Qwen (Alibaba Cloud)
Çeviri Aracı
Google Gemini
Google Gemini

Paylaş