…YZ’nin kare süresindeki payını ölçebilecek, pahalı işleri karelere yayıp kuyruğa alabilecek, NPC’leri önemlerine göre farklı ayrıntıda çalıştırabilecek ve “bu optimizasyon gerçekten gerekli mi?” sorusunu veriyle cevaplayabileceksiniz.
Her NPC her karede çevresini görmek için 10 ışın (raycast) atıyor. Sahnede 500 NPC var ve oyun 60 FPS. Saniyede kaç ışın?
Yeşil = gerekli · kesikli = faydalı ama şart değil. Tıklayınca ilgili sunuma gider.
| frame budget · frame time | kare bütçesi · kare süresi | Bir karede harcanabilecek süre (60 FPS → 16,7 ms) · gerçekte harcanan süre |
| spike · hitch · 1% low | sıçrama · takılma · en kötü %1 | Tek bir karenin çok uzaması · oyuncunun hissettiği donma · en yavaş karelerin ortalaması |
| profiler · marker | profilleyici · işaretçi | Kodun nerede ne kadar süre harcadığını ölçen araç · ölçülecek kod bölümü |
| time slicing · staggering | zaman dilimleme · kademelendirme | İşi birden çok kareye yaymak · ajanların güncellemelerini farklı karelere dağıtmak |
| LOD (level of detail) | ayrıntı düzeyi | Önemsiz şeyi daha ucuz/seyrek hesaplamak |
| starvation | açlık | Bir ajanın sırası hiç gelmemesi |
| spatial partitioning | uzaysal bölümleme | Izgara, dörtlü ağaç: “yakınımda kim var?” sorusunu hızlandıran yapılar |
| DOD · ECS · cache miss | veri odaklı tasarım · varlık-bileşen-sistem · önbellek ıskası | Veriyi işlenme biçimine göre düzenlemek · Unity DOTS mimarisi · işlemcinin veriyi bellekten beklemesi |
| hedef | kare başına |
|---|---|
| 30 FPS (bazı konsol oyunları) | 33,3 ms |
| 60 FPS (çoğu oyun) | 16,7 ms |
| 120 FPS (rekabetçi, VR’ye yakın) | 8,3 ms |
Durum: “Dişler oyunu yavaşlattı” → büyük ölçüde efsane. “Eksik LOD performansı düşürdü” → gerçek.
Tek garsonlu bir lokantada 30 masa var. Garson her dakika her masaya uğramaya çalışsa koşmaktan hiçbir siparişi alamaz. Bunun yerine sırayla dolaşır: bu dakika 1–10, sonraki 11–20, sonraki 21–30.
Oyunda garson = YZ bütçesi, masalar = NPC’ler. Yandaki tablo 6 NPC’nin her karede ikisini düşündürür: her NPC 3 karede bir karar verir. 60 FPS’te bu, saniyede 20 karar: insandan bile hızlı.
| kare 1 | kare 2 | kare 3 | kare 4 | kare 5 | kare 6 | |
|---|---|---|---|---|---|---|
| 🧟 A | 🧠 | · | · | 🧠 | · | · |
| 🧟 B | · | 🧠 | · | · | 🧠 | · |
| 🧟 C | · | · | 🧠 | · | · | 🧠 |
| 🧟 D | 🧠 | · | · | 🧠 | · | · |
| 🧟 E | · | 🧠 | · | · | 🧠 | · |
| 🧟 F | · | · | 🧠 | · | · | 🧠 |
🧠 = o karede bu NPC düşünüyor (algıla + karar ver). · = önceki kararına devam ediyor (yürümeye, ateş etmeye). Her kare yalnızca 2 NPC’nin maliyeti ödenir.
Aynı konuyu başka bir anlatımla, kendi elinizle oynayarak görmek çok işe yarar. Kartlar yeni sekmede açılır; çoğu İngilizce ama görsel ve etkileşimli.
Grafikte uzaktaki ağaç daha az üçgenle çizilir; kimse fark etmez. YZ’de de aynı fikir: oyuncudan uzaktaki NPC daha az düşünür.
| halka | ne yapılır? | sıklık |
|---|---|---|
| yakın | görüş ışınları, davranış ağacı, tam A* | her kare |
| orta | basit kurallar, önceden pişmiş yollar | 5 karede bir |
| uzak | yalnızca konum ilerler, animasyon yok | saniyede bir |
Ama uzaklık her zaman doğru ölçüt değil: oyuncunun dürbünle izlediği şüpheli uzakta olsa da tam ayrıntı hak eder. Sonraki slayttaki “LOD Trader” tam bunu çözüyor.
Ben Sunshine-Hill (Game AI Pro, 14. bölüm): uzaklık eşikleri yetersizdir; kalabalık oyuncunun yanına gelirse bütçe patlar, seyrek alanlarda ise ayrıntı gereksiz yere kısılır.
Massive Crowd on Assassin’s Creed Unity: AI Recycling
GDC · 38 dk · YouTube’da aç
Az önceki halkaların gerçek oyundaki hâli: binlerce kişilik kalabalığın çoğu ucuz, düşük ayrıntılı temsilciler; oyuncu yaklaşınca biri havuzdan alınan “gerçek” bir YZ’ye dönüşüyor. İlk 12 dakika ana fikri veriyor.
açlık = başlangıç + hız · geçen süre.Intro to Data Oriented Design for Games
Nic Barker · 52 dk · YouTube’da aç
Az önceki AoS/SoA çiziminin uzun ve çok görsel anlatımı: işlemci önbelleği nasıl çalışır, bir oyun döngüsü neden “nesne nesne” değil “alan alan” yazılınca hızlanır. İlk 15 dakika bu sunum için yeterli.
Burst ile basit sayısal döngüler genelde düz C#’tan kat kat hızlı çalışır; ama ölçmeden varsaymayın. Fizik ışınları için toplu sorgu: RaycastCommand.ScheduleBatch.
| Stopwatch · Elapsed.TotalMilliseconds | kronometre | Kod içinde süre ölçmek |
| ProfilerMarker · .Auto() | profil işaretçisi | using bloğu süresince ölçüm; Unity Profiler’da adıyla görünür |
| interface IAIAgent | arayüz | “Think() metodu olan her şey”; zamanlayıcı türden bağımsız çalışır |
| struct · IJobParallelFor · Execute(i) | iş yapısı | Her indis için ayrı çalışan, çekirdeklere dağıtılan iş |
| NativeArray · [ReadOnly] · Dispose | yerel dizi | Çöp toplayıcı dışı bellek; salt okunur işaret; elle serbest bırakma |
| cProfile · pstats | Python profilleyici | Fonksiyon başına süre ve çağrı sayısı |
| performance.now() | yüksek çözünürlüklü zaman | Tarayıcıda milisaniye ölçümü |
| ad | platform | ne yapar / sınırları | nasıl eklenir |
|---|---|---|---|
| Unity Profiler · Profile Analyzer | Unity | CPU/GPU/bellek zaman çizelgesi, ProfilerMarker satırları, iki ölçümü karşılaştırma; hedef cihaza bağlanarak ölçüm. | Window → Analysis → Profiler; Package Manager → Profile Analyzer |
| Unreal Insights · stat komutları | Unreal | İz (trace) tabanlı ayrıntılı profil; stat unit, stat game, AI hata ayıklayıcısı (Gameplay Debugger). | Motorla birlikte |
| Godot Profiler · Monitors | Godot 4 | Betik fonksiyonu başına süre, fizik/navigasyon sayaçları, özel monitörler. | Debugger paneli |
| Tracy | C/C++ (bağlamalar: C#, Lua, Python…) | Açık kaynak, nanosaniye çözünürlüklü kare profilleyicisi; çok iş parçacıklı zaman çizelgesi. | GitHub sürümü |
| Unity Entities · Jobs · Burst | Unity | ECS, çok çekirdekli işler, yüksek performanslı derleyici. | Package Manager |
| Unreal Mass | Unreal 5 | Binlerce varlık için veri odaklı kalabalık/trafik çerçevesi (MassEntity, MassAI). | Plugins → MassEntity, MassAI |
“Unity 6, C#. Bir AIScheduler yaz: (1) IAIAgent arayüzü (Think(), DistanceToPlayer, IsVisible, IsPlayerTarget). (2) Her kare 2 ms bütçe (Stopwatch). (3) Öncelik: oyuncunun hedefi ve 15 m içindekiler her kare; görünür olanlar en fazla 5 karede bir; görünmeyenler en fazla 30 karede bir; kalan bütçe en uzun süredir güncellenmeyene. (4) ProfilerMarker ile “AI.Think” ölçümü ve kare başına güncellenen ajan sayısını Profiler Counter olarak yayınla. (5) Sahne görünümünde her ajanın üstünde son güncellemeden bu yana geçen kare sayısını renkli gösteren Gizmos. (6) 1000 ajanla en kötü durum performans testi (PlayMode test).”
Adı geçen oyunu tanımıyorsanız: oyuncuların kullandığı wiki sayfası ve oyunu kısaca gösteren bir video. ▶ video slaydın üstünde açılır (Esc ile kapanır); 🎯 işaretli bağlantılar doğrudan bu sunumdaki konuya gider.
Massive Crowd on Assassin’s Creed Unity: AI Recycling
Data-Oriented Design and C++
Boosting your game performance with Unity 6 Profiling tools
Check Game Performance with Unity Profiler
Unreal Engine 5 Tutorial: Mass Entity Crowds
When Regular Pathfinding Isn’t Enough (akış alanları)
“Game Development in Eight Bits”