Masuk ke inti profesi game developer: merancang player controller, input handling, dan game mechanics yang terasa enak dimainkan, lalu membangun gameplay loop Rimba Runner yang utuh — lompat, lari, kumpulkan buah, dan hindari rintangan

Tiga episode terakhir mengenalkan kalian pada tiga engine. Mulai episode ini, kita fokus pada hal yang membedakan game developer dari sekadar "orang yang tahu engine": gameplay programming — seni menerjemahkan aturan desain menjadi mekanik yang benar-benar terasa enak di tangan pemain.
Gameplay programming adalah jantung peran game developer. Di sinilah keputusan desain ("lompatan harus terasa ringan dan responsif") bertemu dengan kode (jumpVelocity = 12), dan di sanalah game dirasakan benar-benar menyenangkan atau justru frustasi. Kita bangun gameplay loop Rimba Runner yang utuh: lari, lompat ganda, mengumpulkan buah, dan bertabrakan dengan rintangan.
Pitfall klasik pemula: menulis kode yang terikat langsung ke tombol tertentu, misalnya if (Input.GetKeyDown(KeyCode.Space)). Masalahnya, pemain ingin remapping kontrol, dan game harus jalan di keyboard, gamepad, dan layar sentuh. Solusi industrinya: abstract input — tombol dipetakan ke "aksi" bernama, lalu kode hanya membaca aksi.
Di Unity, gunakan Input System package dengan Action Assets. Di Godot, mekanismenya built-in lewat Input Map. Di Unreal, lewat Enhanced Input. Contoh Godot — definisikan aksi jump di Project Settings → Input Map, lalu baca di kode:
extends CharacterBody2D
@export var run_speed := 300.0
@export var jump_velocity := -500.0
var gravity := 1200.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
var move := Input.get_axis("move_left", "move_right")
velocity.x = move * run_speed
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
move_and_slide()Kunci kode di atas: get_axis untuk input analog kiri/kanan, is_action_just_pressed untuk lompat (memicu sekali, bukan terus-menerus), dan is_on_floor() untuk memastikan pemain tidak melompat di udara. Ini gameplay loop inti — dibaca dari input, diproses, lalu dirender oleh engine.
Gameplay terasa enak bukan kebetulan — ada teknik desain yang membuat kontrol terasa "lebih murah hati" dari realita. Dua teknik wajib untuk platformer:
const COYOTE := 0.1
const BUFFER := 0.15
var coyote_timer := 0.0
var jump_buffer_timer := 0.0
func _physics_process(delta: float) -> void:
coyote_timer = COYOTE if is_on_floor() else max(0.0, coyote_timer - delta)
jump_buffer_timer = BUFFER if Input.is_action_just_pressed("jump") else max(0.0, jump_buffer_timer - delta)
if jump_buffer_timer > 0.0 and coyote_timer > 0.0:
velocity.y = jump_velocity
jump_buffer_timer = 0.0
coyote_timer = 0.0Bandingkan dengan versi sebelumnya: sekarang lompatan "memaafkan" ketidaksempurnaan input. Perubahan kecil di kode, perbedaan besar di game feel — inilah yang membedakan platformer enak dari platformer membuat frustasi. Kita dalami game feel lebih jauh di episode 17.
Gameplay loop dibangun dari beberapa mekanik yang saling mengunci. Di Rimba Runner: lari + lompat (kontrol), kumpulkan buah (hadiah), hindari rintangan (bahaya), dan skor (progression jangka pendek). Mari tambahkan buah sebagai Area2D dengan signal (persis pola episode 4):
extends Area2D
signal collected(points: int)
@export var points := 10
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("player"):
collected.emit(points)
queue_free()Dan nyawa/restart saat terkena rintangan — memakai group untuk deteksi:
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("obstacle") and current.is_in_group("player"):
GameState.health -= 1
if GameState.health <= 0:
get_tree().reload_current_scene()Dua mekanik itu — hadiah dan bahaya — plus kontrol yang enak, sudah membentuk game yang bisa dimainkan. Itulah minimal viable gameplay loop: aksi pemain → konsekuensi → umpan balik, berulang.
Semakin banyak mekanik, semakin besar risiko kode jadi kusut. Tiga disiplin yang menyelamatkan:
@export atau config, sehingga designer bisa tuning tanpa masuk ke logika.Tip
Aturan emas gameplay programming: kode harus mengungkapkan maksud desain. Kalau kalian membaca coyote_timer, orang lain langsung tahu ini untuk kompensasi lompatan. Hindari nama variabel generik seperti t1, x2, flag. Kode yang jelas = tim yang cepat dan bug yang sedikit.
Important
Prinsip abstraction input bukan teori — ini praktik wajib. Begitu game kalian dirilis di lebih dari satu platform (keyboard + gamepad + touch), kode yang terikat tombol akan memaksa kalian menulis ulang seluruh controller. Mulai dengan action-based input sejak prototipe.
Gameplay programming adalah keterampilan yang kalian asah setiap hari sepanjang karir.
Inti yang harus dibawa pulang:
Di episode 7 selanjutnya kita akan membekali diri dengan matematika di balik semua gerakan: math & physics game — vector, matrix, transform, dan collision detection, lengkap dengan implementasi physics sederhana. Sampai jumpa di episode 7!