Menjaga game tetap mulus di semua perangkat: memahami frame budget, profiling berbasis data, dan optimasi draw calls, physics, serta memori, lalu praktik menemukan dan memperbaiki bottleneck di Rimba Runner

Game yang lambat menghancurkan segalanya — gameplay yang dirancang berbulan-bulan terasa payah jika frame-nya patah-patah. Performance optimization bukan sekadar "membuat game cepat", melainkan menjaga game tetap dalam budget di semua perangkat target, dari PC gaming hingga HP menengah.
Episode ini mengajarkan pendekatan optimasi yang benar. Dan kata kuncinya adalah data: optimasi tanpa ukuran adalah tebakan. Kita akan paham frame budget, belajar profiling untuk menemukan bottleneck nyata, lalu membahas optimasi draw calls, physics, dan memori dengan studi kasus Rimba Runner.
Setiap frame punya anggaran waktu. Pada 60 fps, satu frame hanya 16,6 ms. Kalau frame melebihi budget, game terasa lambat (stutter). Kalau terus-menerus, fps turun. Mari hitung anggarannya:
Simulasi/logika : ± 4 ms
Physics : ± 3 ms
Rendering : ± 6 ms
GPU work : ± 3 ms
Total : 16,6 ms (maksimal)Angka di atas hanya contoh — yang penting adalah kesadaran: waktu per frame adalah sumber daya yang bisa habis. Semua yang kita tambahkan (AI musuh, partikel, shader, pencahayaan) memakan porsi budget. Tugas optimasi adalah memastikan porsi itu wajar.
Aturan emas optimasi:
Profiler adalah alat yang mengukur di mana waktu per frame dihabiskan. Tiap engine punya profiler bawaan: Godot (Debugger/Profiler, Renderer Debugger), Unity (Profiler window, Frame Debugger), Unreal (Unreal Insights, stat GPU). Ada juga alat eksternal seperti RenderDoc (GPU) dan Perfetto (sistem).
Alur profiling yang benar:
Yang sering salah: mengoptimasi berdasarkan firasat. "Pasti banyak musuhnya yang bikin lambat." Mungkin saja benar — tapi mungkin juga bottleneck-nya justru partikel, atau pemuatan tekstur, atau garbage collection di script. Profiler menyingkirkan firasat.
Saat memprofil, jaga disiplin: profil pada scene yang representatif (level penuh, bukan test scene kosong), di perangkat terlemah yang menjadi target (bukan mesin dev yang super kencang), dan dengan build release bila memungkinkan (mode debug editor jauh lebih lambat).
Draw call adalah perintah "gambar objek ini" yang dikirim CPU ke GPU. Masalahnya: tiap draw call butuh waktu pengiriman. Ribuan draw call per frame membuat CPU jadi bottleneck meski GPU nganggur.
Sumber draw call berlebihan di game 2D:
Solusi standar:
Cara melihat dampaknya: buka statistik renderer. Di Godot, Renderer Debugger menampilkan jumlah draw calls; jika ribuan padahal scene sederhana, ada yang salah.
Dua kategori yang sering jadi pembunuh performa diam-diam:
Physics — tiap rigidbody yang aktif berpartisipasi dalam simulasi collision. Masalah umum: ratusan rigidbody aktif padahal kebanyakan statis. Perbaikan: gunakan StaticBody untuk objek diam, batasi jumlah rigidbody aktif, perbesar collision margin bila aman, dan matikan physics untuk objek di luar layar.
Memori — allocation berlebihan di update loop menyebabkan garbage collection (GC) yang memicu stutter. Contoh klasik: membuat string baru tiap frame, atau objek sementara di dalam _process. Di Godot/GDScript dan Unity C#, alokasi per-frame adalah musuh stutter:
# Buruk: membuat string & array baru tiap frame
func _process(delta):
label.text = "Skor: " + str(score) # alokasi string baru tiap frame
var temp = [1, 2, 3] # alokasi array baru tiap frame
# Baik: simpan hasil yang bisa disimpan
func _process(delta):
if score != last_score:
label.text = "Skor: " + str(score)
last_score = scorePrinsipnya: jangan buat sampah di dalam loop. Semua yang bisa dihitung di luar update (precompute), di luar loop (konfigurasi sekali), atau di-cache, lakukan di sana.
Tip
Tetapkan target platform terendah di awal project — misal "harus 60 fps di HP kelas menengah". Keputusan teknis (jumlah particle, ukuran tekstur, kompleksitas shader) jadi jauh lebih mudah karena ada garis yang jelas. Tanpa target, optimasi tak pernah selesai karena tak ada definisi "cukup baik".
Ikuti alur data-driven:
Bottleneck awal : 5.200 draw calls, frame 28 ms
Setelah atlas : 1.100 draw calls, frame 18 ms
Setelah batching : 640 draw calls, frame 15 ms ← masuk budget 60 fpsWarning
Jangan mengorbankan gameplay demi angka benchmark. Optimasi yang merusak desain (menghapus fitur, menurunkan kualitas visual drastis) harus dikonsultasikan dengan tim desain dulu — ingat kolaborasi di episode 1 dan 17. Performa melayani gameplay, bukan sebaliknya.
Optimasi adalah disiplin mengukur, bukan menebak.
Inti yang harus dibawa pulang:
Di episode 17 selanjutnya kita akan mengasah kerja sama inti: game design collaboration — bekerja dengan designer, memahami game feel & mechanics, dan iterasi desain, lengkap dengan praktik iterasi desain Rimba Runner. Sampai jumpa di episode 17!