Scripting II: Mastering Script Flow
Menguasai alur cerita yang kompleks: loop, Python block, manajemen state, sistem hari, dan arsitektur multi-file. Pertemuan ini membawa kemampuan scripting kamu ke level profesional.
Target Kompetensi
Mahasiswa mampu mengimplementasikan loop, Python block, sistem hari, dan arsitektur multi-file dalam proyek Ren'Py, serta mengelola state cerita yang kompleks dengan efisien.
Recap: Apa yang Sudah Kamu Kuasai?
P1-P3: Fondasi
Instalasi Ren'Py, label, jump, call, return, konversi mindmap ke kode.
P4: Logika
Variabel (default/define/$), kondisional (if/elif/else), menu pilihan bersyarat.
P5-P6: Visual
Aset gambar (scene/show/hide), transisi, ekspresi karakter, staging, dialog lanjutan.
Sekarang kita akan merangkai semua ini menjadi sistem yang lebih cerdas dan terstruktur.
While Loop: Mengulang Logika
Loop di Ren'Py memungkinkan pengulangan aksi tertentu tanpa menulis kode yang sama berkali-kali.
# Loop dasar untuk menu yang berulang
label ruang_belajar:
scene bg_perpustakaan
n "Kamu berada di perpustakaan. Mau apa?"
while True: # Loop tanpa batas, harus ada 'break' untuk keluar
menu:
"Baca buku teori (+5 pengetahuan)":
$ pengetahuan += 5
n "Kamu membaca bab tentang manajemen proyek."
"Kerjakan latihan soal (+8 pengetahuan, -2 stamina)":
$ pengetahuan += 8
$ stamina -= 2
n "Mengerjakan soal memang melelahkan tapi efektif."
"Selesai belajar, pulang ke kost":
break # Keluar dari while loop
if stamina <= 0:
n "Kamu terlalu lelah untuk melanjutkan belajar."
break
jump scene_pulang
Loop while True: tanpa kondisi break yang dapat tercapai akan membuat game stuck selamanya. Selalu pastikan ada minimal satu kondisi keluar (break) yang bisa dicapai.
Python Block: Kekuatan Penuh Python di Ren'Py
Untuk logika yang lebih kompleks, kamu bisa menggunakan blok Python penuh di dalam skrip Ren'Py.
# Blok Python untuk logika kompleks
label hitung_ending:
python:
# Kode Python murni di dalam blok ini
total_poin = afeksi_nabilah + afeksi_ahmad
if total_poin >= 80:
kategori_ending = "sempurna"
elif total_poin >= 50:
kategori_ending = "baik"
else:
kategori_ending = "biasa"
# Bisa pakai list, dict, dll
pencapaian = []
if event_belajar_bareng:
pencapaian.append("Teman Belajar")
if event_konflik:
pencapaian.append("Menghadapi Konflik")
# Setelah blok, lanjut dengan Ren'Py normal
if kategori_ending == "sempurna":
jump ending_terbaik
elif kategori_ending == "baik":
jump ending_baik
else:
jump ending_biasa
# Init Python: dijalankan sebelum game dimulai
init python:
def hitung_level(poin):
"""Fungsi utilitas untuk menghitung level"""
if poin >= 80: return "Luar Biasa"
if poin >= 60: return "Baik"
if poin >= 40: return "Cukup"
return "Perlu Ditingkatkan"
Multi-file Project: Mengorganisir Kode
Ketika proyek makin besar, satu file script.rpy akan menjadi sangat panjang dan sulit dikelola. Ren'Py mendukung penggunaan banyak file .rpy dalam satu proyek.
game/
├── script.rpy ← Titik awal (label start) dan settings global
├── karakter.rpy ← Semua definisi Character()
├── variables.rpy ← Semua default variables
├── chapter_01.rpy ← Cerita bab 1
├── chapter_02.rpy ← Cerita bab 2
├── ending.rpy ← Semua label ending
├── screens_kustom.rpy ← Layar kustom
└── functions.rpy ← Init python dan fungsi utilitas
Ren'Py secara otomatis membaca dan menggabungkan semua file .rpy dalam folder game/. Kamu tidak perlu "import" atau "include". Cukup buat file baru dan Ren'Py akan menemukannya.
Contoh Pembagian File yang Rapi
# === variables.rpy ===
# Semua variabel default proyek
default hari = 1
default stamina = 10
default pengetahuan = 0
default afeksi_nabilah = 0
# Event flags
default e_pertemuan_nabilah = False
default e_konflik_utama = False
default e_resolusi = False
# === karakter.rpy ===
# Semua definisi karakter
define n = Character("Nabilah", color="#c8ffc8")
define a = Character("Ahmad", color="#ffc8c8")
define d = Character("Dosen Pembimbing", color="#88ddff")
define narr = Character("")
State Machine: Mengelola Kondisi Game
State machine adalah pola desain yang membantu mengelola kondisi game yang kompleks. Alih-alih variabel booleans yang bertebaran, gunakan satu variabel "state" yang jelas.
# Alih-alih banyak boolean terpisah:
default sudah_ketemu = False
default sudah_berteman = False
default sudah_konflik = False
default sudah_damai = False
# Gunakan satu variabel state yang lebih jelas:
default status_hubungan = "asing"
# Nilai: "asing" -> "kenalan" -> "teman" -> "konflik" -> "sahabat" atau "putus"
label pilihan_ramah:
$ status_hubungan = "kenalan"
label pilihan_belajar_bareng:
if status_hubungan == "kenalan":
$ status_hubungan = "teman"
label cek_hubungan:
if status_hubungan == "sahabat":
jump ending_terbaik
elif status_hubungan == "teman":
jump ending_baik
else:
jump ending_biasa
Rollback: Mengelola Fitur Undo
Ren'Py memiliki fitur rollback bawaan yang memungkinkan pemain kembali ke dialog sebelumnya. Kamu bisa mengendalikan kapan rollback diizinkan.
# Menonaktifkan rollback untuk momen tertentu
# (agar keputusan penting tidak bisa di-undo)
label pilihan_kritis:
n "Ini keputusan final. Pikirkan baik-baik."
menu:
"Laporkan ke dosen":
$ renpy.block_rollback() # Blokir rollback setelah pilihan ini
$ sudah_lapor = True
jump ending_lapor
"Simpan untuk diri sendiri":
$ renpy.block_rollback()
jump ending_diam
Memblokir rollback untuk pilihan penting menciptakan konsekuensi nyata. Pemain tidak bisa seenaknya mencoba semua opsi tanpa risiko. Ini membuat pilihan terasa lebih berarti dan dramatis.
Day System: Cerita Berbasis Waktu
Sistem hari membuat cerita terasa memiliki dimensi waktu. Pemain merasa seperti benar-benar menjalani hari demi hari bersama karakter.
default hari = 1
default stamina = 5 # Stamina per hari
label transisi_hari:
# Tampilkan pergantian hari
scene bg_black with fade
$ hari += 1
$ stamina = 5 # Reset stamina setiap hari baru
narr "--- Hari ke-[hari] ---" # [hari] = nilai variabel hari
if hari == 7:
narr "Hari terakhir sebelum ujian."
jump chapter_final
else:
jump awal_hari_baru
label awal_hari_baru:
scene bg_kampus_pagi with fade
narr "Pagi hari. Stamina hari ini: [stamina]."
while stamina > 0:
menu:
"Kuliah (-2 stamina, +10 pengetahuan)":
$ stamina -= 2
$ pengetahuan += 10
jump aktivitas_kuliah
"Kunjungi Nabilah (-1 stamina, +10 afeksi)":
$ stamina -= 1
$ afeksi_nabilah += 10
jump aktivitas_nabilah
"Istirahat (hari berakhir)":
break
jump transisi_hari
Checklist Proyek Mid-Semester
Gunakan checklist ini untuk memastikan proyekmu sudah sesuai harapan sebelum lanjut ke fase polishing.
Proyek punya folder struktur yang benar (game/images, game/audio)
Ada minimal 3 label yang berbeda dan terhubung
Ada minimal 1 menu pilihan dengan percabangan yang bermakna
Variabel digunakan untuk mempengaruhi alur cerita
Ada minimal 3 background dan 2 sprite karakter
Ada minimal 2 ekspresi per karakter utama
Transisi digunakan (dissolve, fade)
Dialog terasa natural, tidak seperti buku teks
Ada minimal 2 ending yang berbeda
Kuis Pemahaman Pertemuan 7
Uji Pemahamanmu!
1. Bagaimana cara menggunakan kode dari file .rpy yang berbeda dalam proyek Ren'Py?
2. Apa fungsi dari renpy.block_rollback()?
3. Bagaimana cara keluar dari while True: di Ren'Py?