Belajar Godot - Operational Readiness & Release
Episode 19 of 23

Belajar Godot - Operational Readiness & Release

Episode ini menyiapkan game kalian benar-benar siap rilis: membangun build pipeline otomatis dengan export headless, menjalankan QA dan regression testing dengan kerangka uji GUT, memilih channel distribusi dan strategi update, serta memasang analytics, crash reporting, dan feedback loop.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Di episode 18 kalian sudah merapikan arsitektur proyek: komponen modular, signal sebagai lem antar sistem, dan mekanik yang bisa dipakai ulang. Kode yang rapi itu tadi baru setengah perjalanan — setengah lainnya adalah mengantarnya keluar ke dunia nyata. Banyak game gagal bukan karena kodenya jelek, tapi karena proses rilisnya amburadul: build yang diuji beda dengan build yang dijual, bug yang lolos ke produksi, dan tidak ada cara tahu kenapa pemain berhenti bermain.

Episode 19 ini membahas operational readiness: build pipeline untuk rilis, QA dan regression testing, strategi packaging dan distribusi, serta analytics, crash reporting, dan feedback loop yang menjadikan rilis bukan akhir, melainkan awal dari siklus perbaikan.

Build Pipeline: Dari Editor ke Rilis

Meng-export lewat menu Editor setiap kali rilis itu rapuh — mudah ada langkah terlewat, dan siapa yang menjamin build di laptop kalian sama dengan yang dipakai tester? Jawabannya: export headless via command line. Godot bisa dijalankan tanpa GUI dan mengekspor sesuai preset yang sudah disimpan di export_presets.cfg.

Preset dibuat sekali lewat Project > Export, lalu dipanggil ulang dari terminal:

export-android.sh
godot --headless --export-release "Android" build/game.apk

Untuk beberapa platform sekaligus, taruh semuanya dalam satu skrip pipeline:

build-all.sh
godot --headless --export-release "Linux" build/linux/game.x86_64
godot --headless --export-release "Windows" build/windows/game.exe
godot --headless --export-release "Web" build/web/index.html

Dengan pipeline ini, build bisa dipicu dari CI — misalnya setiap commit ke cabang rilis. Skrip build-all.sh memastikan semua platform keluar dari versi kode yang sama, menghilangkan misteri "di laptop saya jalan".

Export Presets & Konfigurasi Rilis

Preset adalah kunci reproducibility. Ada dua hal yang wajib dikonfigurasi di dalamnya. Pertama, eksklusi file: jangan ikut mengekspor .godot, aset mentah, atau file konfigurasi yang berisi rahasia dev. Kedua, template per platform: Android butuh keystore dan pakai AAB untuk Play Store, Web butuh embed mode yang tepat. Perbedaan ini sebaiknya dicatat sebagai preset terpisah, bukan diubah manual setiap rilis. Semua konfigurasi ini tersimpan di export_presets.cfg dan ikut ter-version-control — audit perubahan export cukup dari diff file itu.

Variabel build juga dipisahkan dari kode. Alih-alih hardcode endpoint atau kunci API, baca dari environment saat game dijalankan:

Pythonconfig.gd
extends Node
 
const ENDPOINT := "https://api.example.com/v1"
const BUILD_NUMBER := "1.2.0"
 
func _ready() -> void:
	print("Running build %s against %s" % [BUILD_NUMBER, ENDPOINT])

Menuliskan BUILD_NUMBER ke layar atau file log terdengar sepele, tapi saat bug datang dari pemain, angka itu satu-satunya petunjuk build mana yang mereka jalankan. Debugging jarak jauh selalu dimulai dari identitas build — tidak mungkin menelusuri bug yang versinya tidak jelas.

QA, Bug Hunting & Regression Testing

QA dimulai dari dalam editor. Godot menyediakan debugger yang bisa menghentikan eksekusi, menginspeksi variabel, dan melompat antar frame. Untuk bug yang hanya muncul saat bermain, hidupkan remote scene tree: lewat tab Debugger, kalian bisa melihat pohon node game yang sedang berjalan di perangkat atau browser — memeriksa nilai live tanpa mencetak ratusan baris print.

Yang tidak boleh ditunda adalah regression testing — memastikan fitur lama tidak rusak saat fitur baru masuk. Di Godot, kebiasaan terbaiknya adalah menulis unit test untuk logika murni (skor, damage formula, state machine) dan mengintegrasikannya ke CI. Kerangka yang paling populer adalah GUT (Godot Unit Test), yang bisa diunduh sebagai plugin.

Regression Testing Otomatis dengan GUT

GUT membungkus logika game dan memanggilnya dari test. Contoh, kita punya formula damage di komponen yang dipakai player dan musuh:

Pythondamage_component.gd
extends Node
 
@export var base_damage: int = 10
 
func calculate_damage(critical: bool) -> int:
	var dmg := base_damage
	if critical:
		dmg *= 2
	return dmg

Test-nya menempati file terpisah di folder res://test/ dan dieksekusi oleh runner GUT:

Pythontest_damage.gd
extends GutTest
 
func test_normal_damage() -> void:
	var comp := preload("res://systems/damage_component.gd").new()
	comp.base_damage = 10
	assert_eq(comp.calculate_damage(false), 10)
 
func test_critical_damage() -> void:
	var comp := preload("res://systems/damage_component.gd").new()
	comp.base_damage = 10
	assert_eq(comp.calculate_damage(true), 20)

Perhatikan bahwa test ini memanggil calculate_damage tanpa melibatkan scene — ia menguji logika murni, sehingga hasilnya deterministik dan cepat. Itulah kenapa kita memisahkan logika dari node di episode 18: yang bisa diuji terpisah, diuji terpisah.

Di CI, GUT dijalankan headless:

test.sh
godot --headless --script res://addons/gut/gut_cmdln.gd -gdir=res://test -gexit

Sekarang setiap perubahan logika damage, misalnya menambah armor, akan langsung ketahuan oleh test_critical_damage jika angkanya meleset. Bug hunting tetap perlu manusia, tapi regression yang membosankan bisa diserahkan ke mesin.

Warning

Jangan menulis test demi mengejar jumlah. Prioritaskan logika yang pernah rusak atau yang paling sering disentuh: damage formula, sistem skor, state machine, dan parser save file. Sepuluh test yang bermakna lebih baik daripada seratus test yang hanya memvalidasi hal sepele.

Packaging, Distribution & Update Strategy

Setelah build hijau dan test lolos, kalian berhadapan dengan channel distribusi. Setiap channel punya konvensi sendiri: Steam dan itch.io menerima binary zip untuk desktop, Google Play mengharuskan AAB yang ditandatangani, App Store menuntut notarisasi. Riset syarat tiap toko jauh sebelum rilis — menunggu sampai build jadi baru membaca aturan adalah resep terlambat.

Strategi update mengikuti channel tersebut:

  • Desktop (Steam/itch.io): branch rilis di git dan tag versi; Steam mengelola update otomatis dari build yang kalian unggah.
  • Android: AAB dengan versi bertambah otomatis; Google Play menangani rollout bertahap ke persentase pemain.
  • Web: satu folder statis yang bisa di-deploy kapan saja; paling mudah untuk hotfix.

Konsistensi nomor versi itu penting. Gunakan semver — major.minor.patch — dan catat perubahan di changelog. Pemain yang melaporkan bug dari versi lama sebaiknya bisa kalian arahkan ke build terbaru, bukan di-diagnosa berdasarkan build yang sudah digantikan.

Analytics, Crash Reporting & Feedback Loop

Rilis bukan garis finis; ia memulai putaran umpan balik. Tanpa data, setiap keputusan (naikkan difficulty? perpendek level 2?) hanya tebakan. Dua instrumen wajib:

  • Analytics event: kapan pemain mulai, berapa lama di tiap level, di mana mereka berhenti. Godot tidak menyediakan analytics bawaan, tapi mengirim event JSON ke layanan analitik bisa dilakukan dengan HTTPRequest biasa.
  • Crash reporting: Godot menyediakan Error.report_callstack() atau push_error() untuk melacak error. Gabungkan dengan logger yang menulis ke file, lalu kirim otomatis saat startup berikutnya.

Skrip minim berikut menangkap error tak tertangani dan menulisnya ke file lokal:

Pythoncrash_logger.gd
extends Node
 
func _init() -> void:
	ErrorHandler.install(self)
 
func report(message: String, stack: String) -> void:
	var file := FileAccess.open("user://crash.log", FileAccess.WRITE)
	file.store_line(message)
	file.store_line(stack)

Feedback loop adalah siklusnya: analytics menunjukkan tempat pemain berhenti, crash log menunjukkan bug yang lolos, test regression memastikan perbaikan tidak merusak yang lain, dan build berikutnya memulai siklus lagi. Tim yang matang melepaskan versi kecil secara rutin dengan ritme ini, bukan sekali melepas dan berdoa.

Success

Mulailah analytics dengan lima event saja: game start, level start, level complete, game over, dan session end. Lima event ini sudah cukup untuk menemukan kebocoran pemain di awal funnel — sisanya ditambahkan saat ada hipotesis spesifik.

Penutup

Episode 19 melengkapi mode produksi kalian: build pipeline yang bisa dipicu dari CI lewat export headless, preset export yang disimpan sebagai sumber kebenaran, QA dengan remote scene tree dan unit test GUT untuk regression, strategi packaging dan update per channel distribusi, serta analytics, crash reporting, dan feedback loop yang menutup siklus perbaikan.

Inti yang harus dibawa pulang:

  • Otomatiskan export dengan godot --headless --export-release dan panggil dari CI agar semua platform keluar dari versi kode yang sama.
  • Simpan nomor build dan konfigurasi rilis sebagai data, bukan nilai ajaib di dalam kode.
  • Tulis unit test dengan GUT untuk logika murni yang sering berubah, dan jalankan headless di pipeline.
  • Sesuaikan packaging dan strategi update dengan aturan tiap toko; versi selalu naik dengan pola semver.
  • Pasang analytics dan crash reporting sedini mungkin agar rilis menjadi awal siklus perbaikan, bukan akhir proyek.

Dengan pipeline yang otomatis dan data yang mengalir, kalian siap merilis dengan percaya diri. Di episode 20 berikutnya kita turun dari proses ke konteks: real-world use cases & project types — bagaimana arsitektur dan alur kerja kalian berubah untuk 2D platformer, puzzle, roguelike, hingga simulation, plus planning, MVP, monetization, dan pola game jam. Sampai jumpa!

Belajar Godot - Operational Readiness & Release | Belajar Godot