Mengunci progres pemain: merancang save system yang aman dan mudah dimigrasi, menata game data dengan JSON, dan merancang progression yang membuat pemain tetap termotivasi, lalu praktik membangun sistem save Rimba Runner

Tidak ada yang lebih membuat pemain frustasi selain progres yang hilang saat game ditutup. Save system adalah janji kepercayaan antara game dan pemain: "apapun yang kalian raih, akan tetap ada." Lebih dari sekadar teknis, save system menyangkut progression design — bagaimana game mengatur hadiah dan tujuan agar pemain tetap termotivasi untuk terus bermain.
Episode ini membangun tiga hal untuk Rimba Runner: save system yang menyimpan skor tertinggi dan unlock level, game data yang ditata rapi dan mudah dimigrasi, serta progression design — alasan kenapa pemain mau kembali bermain.
Pertanyaan pertama yang harus dijawab: apa yang perlu disimpan? Tentukan daftar lengkap sebelum menulis kode — save yang kurang berarti pemain kehilangan progres, save yang berlebihan berarti data usang yang menyulitkan pembaruan.
Untuk Rimba Runner:
Jangan simpan hal-hal yang bisa dihitung ulang: posisi peluru, status musuh sementara, atau variabel debug. Aturan praktisnya: simpan fakta progres, bukan kondisi sesaat.
Format yang paling praktis dan portabel adalah JSON. Godot punya JSON dan FileAccess, Unity punya JsonUtility/Newtonsoft.Json, Unreal punya FJsonObject. Definisi data save Rimba Runner:
{
"version": 1,
"player": { "total_fruits": 42, "highscores": { "level1": 1200, "level2": 900 } },
"unlocked_levels": ["level1", "level2"],
"settings": { "music_volume": 0.8, "sfx_volume": 1.0 }
}Implementasi di Godot:
const SAVE_PATH := "user://save.json"
func save_game(data: Dictionary) -> void:
var file := FileAccess.open(SAVE_PATH, FileAccess.WRITE)
file.store_string(JSON.stringify(data, " "))
file.close()
func load_game() -> Dictionary:
if not FileAccess.file_exists(SAVE_PATH):
return {}
var file := FileAccess.open(SAVE_PATH, FileAccess.READ)
var parsed = JSON.parse_string(file.get_as_text())
file.close()
return parsed if parsed is Dictionary else {}Perhatikan user:// — jalur khusus Godot yang menunjuk ke direktori user sesuai platform (Windows, macOS, Linux, Android, iOS). Di Unity setara Application.persistentDataPath, di Unreal FPaths::ProjectSavedDir. Selalu gunakan jalur user ini, bukan folder game — folder game sering read-only.
Ini masalah paling sering diabaikan pemula: save data yang dibuat versi game lama harus tetap bisa dibaca versi baru. Game terus berubah selama development dan setelah rilis. Strateginya sederhana:
"version": 1 di atas).func migrate(data: Dictionary) -> Dictionary:
var v := int(data.get("version", 0))
while v < CURRENT_VERSION:
v += 1
match v:
2:
data["unlocked_levels"] = data.get("unlocked_levels", ["level1"])
3:
data["settings"] = data.get("settings", {})
data["settings"]["sfx_volume"] = 1.0
data["version"] = CURRENT_VERSION
return dataTanpa versioning, update game yang mengubah format save akan menghapus progres semua pemain — bencana reputasi. Versioning adalah tembok pengaman yang biayanya lima menit tapi menghemat berbulan-bulan.
Save system menyimpan progres; progression design menentukan progres apa yang layak disimpan. Dua konsep inti:
Di Rimba Runner, progression dibangun bertingkat:
Kumpulkan buah → buka skor tinggi per level → buka level baru → total buah → skin karakterYang penting: progression harus memberitahu pemain kemajuannya. HUD menunjukkan total buah dan level yang terbuka; menu level menampilkan bintang/lock per level. Data progres yang tersembunyi sama saja dengan tidak ada progres.
Tip
Jangan mengunci konten utama di balik grind yang ekstrem. Uji progression dengan pemain yang tidak tahu mekaniknya — kalau test player tidak pernah melihat level 2, reward pacing terlalu lambat. Progression paling baik diukur, bukan ditebak.
Important
Saat simpan data yang berisi nilai angka, tulis sebagai string di konfigurasi YAML/markdown jika relevan (contoh "15.0") agar tidak ter-parse sebagai tipe yang salah — ini aturan yang sama seperti data versioning: tipe data yang tidak eksplisit adalah sumber bug diam-diam.
Rakit save system lengkap:
GameData dengan versi, skor, unlock, settings.GameState global yang mengelola data dan menulis/membaca file.NOTIFICATION_WM_CLOSE_REQUEST.Warning
Jangan menulis save di tengah-tengah update physics atau saat banyak objek sedang dimutasi — file bisa korup. Tulis save pada momen yang jelas (game over, transisi level, atau interval background) dan idealnya tulis ke file sementara dulu lalu rename, agar file save lama tidak pernah setengah tertulis.
Save dan progression adalah janji yang membuat pemain percaya.
Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membuat game semakin indah: graphics & rendering — sprites, shader, lighting, dan optimasi visual, lengkap dengan visual pass Rimba Runner. Sampai jumpa di episode 12!