Ren'Py ile
kendi hikayeni yaz
Kod bilmene gerek yok. Bu rehberle 30 dakikada ilk sahnen hazır. Windows, Mac, Android, Web'e tek tuşla yayınla.
Tamamen Ücretsiz
Ticari oyun yapsan bile ödeme yok. Sınırsız export, sınırsız proje.
Kod Bilmene Gerek Yok
Ren'Py'nin kendi basit dili var. Diyalog yazmak kadar kolay.
6 Platforma Export
Windows, Mac, Linux, Android, iOS ve Web: tek proje, hepsi.
Dev Topluluk
Dünyanın en büyük VN motoru. Binlerce oyun, hazır mod ve destek.
Ren'Py Nedir?
Ren'Py, visual novel yapmanın en kolay yolu. Ücretsiz, açık kaynak ve dünyanın en popüler VN motoru.
Onunla neler yapabilirsin:
- Karakter diyalogları, seçenekler, dallanmalar
- Arkaplan ve karakter görselleri
- Müzik, ses efektleri
- Save/Load, ayarlar, geçmiş paneli. hepsi hazır geliyor
- Windows, Mac, Linux, Android, Web'e tek tuşla export
Kurulum
renpy.org/latest.html adresine git. İşletim sistemine göre (Windows/Mac/Linux) indir.
Windows: İndirdiğin .exe dosyasına çift tıkla. Kendi kendine çıkarır. Mac: .dmg dosyasını aç, Applications'a sürükle.
Çıkan klasördeki renpy.exe (Windows) veya renpy.app (Mac) dosyasını çalıştır. Launcher açılır:
Sol tarafta projelerini görürsün. Sağ tarafta "Create New Project", "Preferences" gibi butonlar var.
İlk Projen
Kendi oyununu başlatmak için Launcher'da "Create New Project" tıkla. 3 adımda hazır:
1. Proje Adı
Oyununa bir isim ver. Boşluk ve Türkçe karakter kullanabilirsin.
2. Çözünürlük
Oyunun ekran boyutu. 1920x1080 veya 1280x720 seç. Emin değilsen 1280x720 ile başla, yeterli olur.
3. Renk Şeması
Ren'Py menülerin ve butonların renk tonunu sorar. Birini seç, sonra istediğin gibi değiştirirsin.
Tamamlandıktan sonra proje listesinde görünür. "Open Directory" > "game" ile oyun dosyalarının olduğu klasörü aç.
game/script.rpy dosyasına yazacaksın. Bunu herhangi bir metin düzenleyiciyle açabilirsin. Visual Studio Code kullan, en rahatı o.
Basit Bir Oyun
script.rpy dosyasını aç ve içindeki her şeyi sil. Şunları yaz:
label start:
"Sabah erkenden mahalle kahvecisine geldim."
"Defne" "Günaydın! Bugün ne içersin?"
"Ben" "Bir Türk kahvesi alayım."
"Defne" "Hemen hazırlıyorum!"
return
Şimdi Launcher'da "Launch Project" tıkla. Oyunun çalışıyor!
Neler oldu burada:
label start:: oyunun başlangıç noktası. Her Ren'Py oyunu buradan başlar."Metin": tek başına yazılırsa anlatıcı (narrator) konuşur, adı gözükmez."İsim" "Metin": karakter konuşması. İsim üstte gözükür.return: oyunu bitirir, ana menüye döner.
label start: satırından sonraki her satır 4 boşluk içeriden başlamalı. Ren'Py neyin nereye ait olduğunu bu girintilerle ayırt eder. Yanlış girinti = oyun çalışmaz.
Karakterler (Characters)
Visual novel'de konuşan kişilere karakter denir. Karakter tanımı yapınca Ren'Py diyalog kutusunda o kişinin adını otomatik gösterir, her karaktere ayrı renk verebilirsin. Tanımlamadan da yazabilirsin ama her satırda ismi tekrar yazman gerekir. Tanımla, kısa kodla çağır:
label start:'ın üstüne yaz (girintisiz, satır başından başla)define d = Character('Defne', color="#c8ffc8")
define b = Character('Ben', color="#c8c8ff")
label start:'ın altına yaz (her satır 4 boşluk girintili)label start:
"Sabah erkenden mahalle kahvecisine geldim."
d "Günaydın! Bugün ne içersin?"
b "Bir Türk kahvesi alayım."
d "Hemen hazırlıyorum!"
return
Neler değişti:
define d = Character('Defne', color="#c8ffc8"):dartık "Defne" demek. Yeşil renkte görünecek.d "Metin": tırnak işareti olmadan, direktdyaz.color="#c8ffc8": ismin rengi. Herhangi bir hex renk kodu koyabilirsin.
define satırları en üstte, label start: onların altında. Karıştırırsan oyun hata verir.# ─── 1. BÖLGE: TANIMLAR (en üst, girintisiz) ───
define d = Character('Defne', color="#c8ffc8")
define b = Character('Ben', color="#c8c8ff")
default sade_icti = False
# ─── 2. BÖLGE: HİKAYE (label blokları, 4 boşluk girintili) ───
label start:
d "Günaydın!"
jump bolum2
label bolum2:
d "Devam edelim."
return
Görseller (Images)
Visual novel'de oyuncunun gördüğü iki tür görsel var: arka planlar (mekanlar: kafe, park, sokak) ve karakter sprite'ları (konuşan kişilerin çizimleri). Bu görselleri kendin çizersin, AI ile üretirsin ya da ücretsiz arşivlerden indirirsin. Ren'Py'nin işi bunları ekranda göstermek.
Ren'Py, proje klasöründeki game/images/ klasörünü otomatik tarar. İçine ne koyarsan oyunda kullanabilirsin. Sistem şöyle işler:
1. Görseli klasöre at. Bilgisayarında proje klasörünü aç, game/images/ içine sürükle-bırak. PNG, JPG, WEBP hepsi çalışır.
2. Kodda dosya adıyla çağır. script.rpy'de dosya adını yaz. Uzantıyı (.png, .jpg) yazmana gerek yok, Ren'Py kendisi bulur.
scene bg kafe yaz
├── defne_mutlu.png : karakter çizimi (mutlu hali) → kodda show defne mutlu yaz
└── defne_kizgin.png : aynı karakter (kızgın hali) → kodda show defne kizgin yaz
Defne_Mutlu.png dosyasını show defne mutlu ile çağırırsın.
Arkaplan (scene)
scene bg kafe
with fade
scene ekrandaki her şeyi temizler ve yeni arka plan gösterir. bg kafe yazmak: "images/ klasöründe bg kafe.png (veya .jpg/.webp) adlı dosyayı kullan" demek. Uzantıyı yazmana gerek yok, Ren'Py kendisi bulur.
Karakter Gösterme (show)
show defne mutlu
with dissolve
show arkaplanın üstüne karakter görseli koyar. defne mutlu demek: images/ klasöründe defne mutlu.png veya defne_mutlu.webp adında dosya ara.
Karakter Gizleme (hide)
hide defne
Karakteri ekrandan tamamen kaldırır. Ne zaman lazım? Bir karakterin sahneden tamamen çıkması gerektiğinde. Aynı karakterin farklı bir ifadesine geçmek için kullanmana gerek yok. show defne kizgin yazınca Ren'Py önceki Defne görselini otomatik değiştirir, silip tekrar eklemen gerekmez.
scene bg kafeshow defne mutluKarakter İfadeleri: Dosyaları Nasıl Düzenlersin?
Bir karakterin mutlu, üzgün, kızgın gibi farklı hallerini göstermek istiyorsan her ifade için ayrı bir görsel dosyası oluşturursun. Dosya adının ilk kelimesi karakterin etiketi, ikinci kelimesi ifade adı olur:
show defne mutlu
├── defne_uzgun.png : → show defne uzgun
├── defne_kizgin.png : → show defne kizgin
├── defne_saskin.png : → show defne saskin
├── emre_normal.png : → show emre normal
├── emre_gulumse.png : → show emre gulumse
├── bg_kafe.jpg : → scene bg kafe
└── bg_park.jpg : → scene bg park
defne_mutlu.png → karakter: defne, ifade: mutlubg_kafe.jpg → tür: bg, isim: kafeAlt çizgi (
_) veya boşluk fark etmez, ikisi de aynı şekilde çalışır.
Scriptte ifade değiştirmek çok kolay:
label start:
scene bg kafe
with fade
show defne mutlu
d "Günaydın!"
show defne saskin # önceki defne mutlu otomatik gider
d "Ne? Gerçekten mi?"
show defne kizgin # yine otomatik değişir
d "Bunu yapmamalıydın!"
show ile gösterdiğinde Ren'Py önceki görseli otomatik kaldırır. hide yazman gerekmez.İstersen alt klasörlere ayırabilirsin:
chars/, bg/) kodda yazılmaz. Ren'Py images/ altındaki tüm alt klasörleri otomatik tarar, sadece dosya adına bakar. Klasör düzeni tamamen sana kalmış, istersen hepsini düz images/ içine de koyabilirsin.Görsel Dosya İsimlendirmesi
Dosyayı game/images/'e koyduğunda Ren'Py dosya adını otomatik olarak koda çevirir. Uzantıyı (.png) atar, büyük harfleri küçültür, alt çizgileri boşluğa çevirir. Sonuç: kodda kullanacağın isim.
Defne_Mutlu.png adında dosya var → kodda show defne mutlu yaz. Hepsi bu.Dönüşümün adımlarını merak ediyorsan:
chars/) yok sayılır, sadece dosya adı önemliimage Komutu: Manuel İsimlendirme
Dosya adında tire, sayı veya özel karakter varsa Ren'Py otomatik bulamaz. image komutu ile kendin eşleştirirsin. ÜST BÖLGE'ye yaz (define'ların yanına):
"defne-ifade-mutlu.png"
# Tire veya özel karakter içeren dosyalar için
image logo = "renpy-logo.png"
image defne happy = "defne-ifade-mutlu.png"
image bg gece = "backgrounds/sehir-gece-v2.jpg"
Bundan sonra show defne happy veya scene bg gece yazman yeterli. Ren'Py hangi dosyayı açacağını bilir.
Karakterler: PNG, WEBP, AVIF (şeffaf arkaplan için PNG/WEBP)
Arkaplanlar: JPG, PNG, WEBP, AVIF
Hepsini Birleştirelim
define d = Character('Defne', color="#c8ffc8")
define b = Character('Ben', color="#c8c8ff")
label start:
scene bg kafe
with fade
"Sabah erkenden mahalle kahvecisine geldim."
show defne mutlu
with dissolve
d "Günaydın! Bugün ne içersin?"
b "Bir Türk kahvesi alayım."
show defne saskin
d "Sade mi, şekerli mi?"
return
show defne saskin yazdığın zaman önceki defne mutlu otomatik olarak değişir. Aynı isimdeki (tag) karakter için tek görsel gösterilir.
Geçişler (Transitions)
Bir sahne veya karakter değiştiğinde ekran aniden değişir, bu sert ve yapay görünür. Geçişler bu değişimi yumuşatır: sahne yavaşça belirir (fade), karakter eriyerek değişir (dissolve), görsel kayarak gelir (move). Oyuna sinematik his katar. with komutuyla eklenir:
scene bg kafe
with fade # Siyaha gider, yeni sahne gelir
show defne mutlu
with dissolve # Yavaş yavaş belirir
En çok kullanılan geçişler:
dissolve: yavaş geçiş (en yaygın)fade: siyaha gidip gelir (sahne değişikliği için)None: geçiş yok, anında değişir
Birden Fazla Değişiklik, Tek Geçiş
scene bg park
show defne mutlu at left
with dissolve # Her ikisi aynı anda geçiş yapar
Burada tek bir with var. Ren'Py üstteki tüm değişiklikleri toplar, hepsini aynı anda oynatır: arka plan ve karakter birlikte dissolve olur.
Ardışık Geçiş: Önce Sahne, Sonra Karakter
Peki ya arka planın önce gelmesini, karakterin sonra belirmesini istiyorsan? Her değişikliğin altına ayrı with koy. Böylece Ren'Py birincisini bitirir, sonra ikincisine geçer:
show defne mutlu
with dissolve
with fade
show defne mutlu
with dissolve
scene bg park
with fade # Önce arka plan kararır, park açılır
show defne mutlu at left
with dissolve # Sonra Defne ayrıca belirir
with None
with dissolve
belirir gibi görünür
scene bg park
with None # Park hazırlandı ama geçiş gösterilmedi
show defne mutlu
with dissolve # Sadece karakter geçişi görülür
Tüm Yerleşik Geçişler
Bunlar ek mod gerektirmez. Ren'Py'ye dahil. with yazdıktan sonra aşağıdakilerden birini yaz:
# ── Sahne değiştirme ───────────────────────────────────────────────
with fade # Siyaha kararak gider, yeni sahne siyahtan açılır
with dissolve # Önceki üstüne yavaş yavaş erir (en çok kullanılan)
with ease # dissolve gibi ama hız: yavaş başlar, ortada hızlanır, yavaşlar
# ── Kaydırma (slide) ───────────────────────────────────────────────
with moveinright # Yeni sahne sağdan kayarak girer
with moveinleft # Yeni sahne soldan kayarak girer
with moveintop # Yeni sahne alttan yukarı kayarak girer
with moveinbottom # Yeni sahne üstten aşağı kayarak girer
with moveoutright # Eski sahne sağa kayarak çıkar
with moveoutleft # Eski sahne sola kayarak çıkar
# ── Perde efektleri ────────────────────────────────────────────────
with wiperight # Yeni sahne soldan sağa doğru perde gibi açılır
with wipeleft # Yeni sahne sağdan sola doğru perde gibi açılır
with wipeup # Yeni sahne aşağıdan yukarı doğru açılır
with wipedown # Yeni sahne yukarıdan aşağı doğru açılır
with blinds # Yatay jaluzi (stor perde) şeklinde açılır
with squares # Küçük kareler halinde rastgele belirir
# ── Sarsıntı (punch): shock/patlama anı ───────────────────────────
with vpunch # Ekran dikey sarsıntısı: patlama, ani darbe için
with hpunch # Ekran yatay sarsıntısı: güçlü vuruş, feryat için
# ── Özel efektler ──────────────────────────────────────────────────
with pixellate # Ekran pikselleşir, sonra yeni sahne çözünür (retro geçiş)
with irisin # Ortadan dışa doğru daire açılır (klasik sinema geçişi)
with irisout # Dıştan merkeze doğru daire kapanır (sahne sonu)
with zoomin # Yeni sahne yakınlaşarak girer (zoom in)
with zoomout # Yeni sahne uzaklaşarak girer (zoom out)
with zoominout # Eski zoom-in ile çıkar, yeni zoom-out ile girer
# ── Genel ──────────────────────────────────────────────────────────
with None # Geçiş yok: ekranı sessizce hazırla, sonra with dissolve ile getir
Zaman Geçişi: Gündüz'den Geceye
VN'lerde zaman geçişi için sahneyi yavaşça karartırsın. İki farklı arka plan görseli lazım (gündüz + gece), aralarına yavaş Dissolve() koy:
# ÜST BÖLGE: define'ların yanına yaz
define gunduz_gece = Dissolve(4.0) # 4 saniyede yavaşça geçer
define hizli_aksam = Dissolve(1.5) # 1.5 saniye: hızlı sahne kesilmesi
scene bg_park_gunduz
with dissolve
kai "Buluşmayı bekliyordum..."
scene bg_park_gece
with gunduz_gece # 4 saniyede gündüz görüntüsü yavaşça gece oluyor
kai "Saatler geçmiş."
with Fade(1.0, 0.5, 1.0) koy, ekran önce siyaha gider, "zaman atlaması" hissi verir.Geçiş Hızını Ayarlama
Yerleşik geçişlerin varsayılan süresi yaklaşık 0.5 saniyedir. Yavaşlatmak veya hızlandırmak için Dissolve(), Fade() gibi sınıfları kullan:
define yavas_giris = Dissolve(1.5) # 1.5 saniyede dissolve
define hizli_fade = Fade(0.2, 0.0, 0.2) # 0.2s kararma, 0s bekle, 0.2s açılma
define dramatik_fade = Fade(0.5, 1.0, 0.5) # 0.5s kararma, 1s tam siyah, 0.5s açılma
scene bg kafe
with dramatik_fade
Pozisyonlar (Positions)
Birden fazla karakter sahnedeyken hepsi üst üste ortada durmasın diye konumlandırma yaparsın. Bir karakter solda, biri sağda, kimin konuştuğu görsel olarak belli olur. at komutuyla karakteri ekranın istediğin yerine koyarsın:
show defne mutlu at left # Solda
show defne mutlu at right # Sağda
show defne mutlu at center # Ortada (varsayılan)
show defne mutlu at truecenter # Tam ortada (dikey+yatay)
# Ekran dışı pozisyonlar: giriş/çıkış animasyonları için
show defne mutlu at offscreenleft # Sol dışında (görünmez)
show defne mutlu at offscreenright # Sağ dışında (görünmez)
offscreenleft ve offscreenright karakteri ekranın tamamen dışına koyar. Genellikle move geçişiyle birlikte kullanılır: karakter ekran dışından yürüyerek girer veya çıkar.Birden fazla karakter aynı anda gösterirken farklı pozisyonlar kullan:
show defne mutlu at left
show emre dusunceli at right
with dissolve
Özel Konum: xalign / yalign
Hazır konumlar (left, right, center) yetmiyorsa sayıyla tam konum ver. xalign: 0.0 = sol kenar, 0.5 = tam orta, 1.0 = sağ kenar. yalign: 0.0 = üst, 1.0 = alt:
show defne mutlu at Position(xalign=0.2, yalign=1.0) # Solda, altta
show emre dusunceli at Position(xalign=0.8, yalign=1.0) # Sağda, altta
Sık kullandığın konumları bir kere transform ile tanımla, sonra ismiyle çağır:
transform sol:
xalign 0.2 yalign 1.0
transform sag:
xalign 0.8 yalign 1.0
# Kullanımı:
show defne mutlu at sol
show emre dusunceli at sag
with dissolve
Müzik ve Ses (Audio)
Ses olmadan visual novel sessiz film gibi kalır. Arka plan müziği sahnenin atmosferini kurar (kafede sakin caz, gerilim anında hızlı ritim), ses efektleri anları güçlendirir (kapı çarpması, bardak sesi). Ses dosyalarını game/audio/ klasörüne koy, kodda çağır. OGG formatı önerilir (küçük boyut, döngüde kesinti yok).
Arka Plan Müziği
Sahne boyunca döngüde çalar. fadeout ile geçiş yumuşak olur.
play music "audio/kafe-ambiyans.ogg" # Başlatır, döngüde çalar
play music "audio/kafe-ambiyans.ogg" fadeout 1.0 # Önceki müzik 1 saniyede solar
stop music fadeout 2.0 # Müziği 2 saniyede durdurur
Ses Efekti
Bir kere çalıp biter. Kapı, adım, patlama gibi anlık sesler için.
play sound "audio/bardak.ogg" # Bir kere çalar, döngü yok
Sıra ile Çalma
İlk parça bitince ikincisi başlar. Birden fazla sahneyi aynı müzik akışıyla kaplarsın.
play music "audio/sabah.ogg"
queue music "audio/ogle.ogg" # Sabah bitince öğle başlar
Gelişmiş Ses Kontrolleri
Müziği yavaşça aç, ses seviyesini ayarla, aynı parçayı boşuna baştan başlatma:
# Müzik 2 saniyede yavaşça açılır (fade in)
play music "audio/kafe.ogg" fadein 2.0
# Hem eski müzik solar, hem yeni yavaşça girer
play music "audio/gece.ogg" fadeout 1.0 fadein 2.0
# Ses seviyesi: 0.0 (sessiz) ile 1.0 (tam) arası
play music "audio/kafe.ogg" volume 0.5 # Yarı ses
# Aynı parça çalıyorsa baştan başlatma
play music "audio/kafe.ogg" if_changed
if_changed çok faydalı: sahne değişse bile aynı müzik çalıyorsa kesintisiz devam eder. Her sahne geçişinde play music yazsan bile müzik kesilmez.game/audio/ klasörüne koy. OGG en yaygın ve hafif olanı.game/audio/'ya koyarsan yolu kısa yazabilirsin: "audio/bardak.ogg" ya da "audio/bardak.ogg": ikisi de çalışır.
Bekleme (Pause)
Bazen diyalog arasında bir an durup sahnenin etkisini hissettirmek istersin: dramatik bir sessizlik, manzaranın tadını çıkarma anı, ya da bir olayın sindirimi. pause komutu oyunu belirli süre bekletir veya oyuncu tıklayana kadar durur.
pause # Oyuncu tıklayana kadar bekle
pause 3.0 # 3 saniye bekle, sonra devam et
scene bg gece_gokyuzu
with fade
"Gökyüzüne baktım. Yıldızlar her zamankinden parlaktı."
pause 2.0 # 2 saniye sessizlik: manzara sindiriliyor
"O an bir dilek tuttum."
pause ile {w} metin etiketinin farkı: pause diyaloglar arasında kullanılır (metin kutusunda bir şey yok). {w} ise metnin ortasında bekleme ekler.
Oyunu Bitirme (Return)
Her hikayenin bir sonu var. Ren'Py'de return komutu oyunu bitirir ve oyuncuyu ana menüye döndürür. Birden fazla son istiyorsan farklı yerlere farklı return'ler koyarsın, oyuncunun seçimlerine göre farklı finallere ulaşır.
"Ve böylece güzel bir gün geçirdim."
"--- SON ---"
return
return bir bitiş noktasıdır. Farklı label'larda farklı return'ler koyarak çoklu sonlar (multiple endings) yapabilirsin. Oyuncu seçimlerine göre farklı label'lara atlatıp her birinin sonunda return yaz.
Butonlar (Buttons & Imagebuttons)
menu: komutu sadece hikaye akışında seçenek sunar. Ama bazen ekranın köşesine bir "Envanter" butonu, bir harita simgesi ya da tıklanabilir bir nesne koymak istersin. Butonlar bunu sağlar, ekranın istediğin yerine metin veya görsel olarak tıklanabilir alan koyarsın. Bunun için screen kullanıyorsun.
screen isim():), sonra istediğin zaman call screen isim ile çağırırsın. Oyuncu seçimini yapınca screen kapanır ve hikaye kaldığı yerden devam eder.Metin Butonu (textbutton)
screen secim_ekrani():
vbox:
textbutton "Devam Et" action Return(True)
textbutton "Ana Menü" action MainMenu()
textbutton "Bir Sahneye Atla" action Jump("sahne3")
label start:
call screen secim_ekrani
Görsel Buton (imagebutton)
screen ozel_menu():
imagebutton:
idle "images/btn_normal.png" # Normal hali
hover "images/btn_hover.png" # Üstüne gelince
action Jump("galeri_label")
Sık Kullanılan action'lar
Jump("label")
Tıklanınca belirtilen label'a atlar. Hikaye dallarına geçiş.
Return(değer)
Screen'i kapatır, değeri döndürür. call screen ile kullanılır.
MainMenu()
Ana menüye döner. Kayıt silinmez.
SetVariable("ad", değer)
Tıklayınca bir değişkeni değiştirir. Ayar toggle'ları için ideal.
vbox = dikey sıralama, hbox = yatay sıralama. Birini diğerinin içine koyarak ızgara düzeni oluşturabilirsin.
Değişkenler (Variables)
Oyuncu bir seçim yaptığında o seçimi hatırlaman lazım. "Kahve mi aldı, çay mı?", "Defne'ye güvendi mi?" gibi bilgileri saklamak için değişken kullanırsın. Sonra bu bilgiye göre hikayeyi dallandırırsın: güven puanı yüksekse iyi son, düşükse kötü son. Kısacası değişkenler oyunun hafızası.
default sade_icti = False
label start:
scene bg kafe
with fade
d "Sade mi, şekerli mi?"
menu:
"Sade olsun.":
$ sade_icti = True
d "Gerçek tiryaki!"
"Şekerli olsun.":
d "Tatlı cansın!"
"Bir saat sonra..."
if sade_icti:
d "Bir sade daha ister misin? İkincisi benden."
else:
d "Şekerli sevdiysen bir de damla sakızlı dene!"
return
default sade_icti = False: oyun başlamadan değişkeni tanımlar. ÜST BÖLGE'ye yaz (define'ların yanına).$ sade_icti = True: değeri değiştirir.$işareti "bu satır Python kodu" demek.if sade_icti:: koşul kontrolü.Trueise altındaki blok çalışır.else:: koşul sağlanmazsa bu blok çalışır.
elif: Birden Fazla Koşul
İki seçenek yetmez, üç-dört farklı durumu kontrol etmen gerekirse elif ("else if"in kısaltması) kullan:
default kahve_tipi = "sade"
label yorum:
if kahve_tipi == "sade":
d "Sade sever, gerçek tiryaki!"
elif kahve_tipi == "sekerli":
d "Tatlı cansın!"
elif kahve_tipi == "sutlu":
d "Latte tipi, modern!"
else:
d "Hmm, ilginç bir tercih."
Akış şöyle işler: Ren'Py yukarıdan aşağı kontrol eder. İlk True olan koşulu çalıştırır, gerisini atlar. Hiçbiri tutmazsa else devreye girer.
True/False, sayı (0, 42), veya metin ("kahve") olabilir. Save/Load'da otomatik kaydedilir.define vs default: Fark Nedir?
Ren'Py'de iki tane "tanımlama" komutu var. İkisi de aynı yere yazılır (label start:'ın üstüne) ama çok farklı işler yapar.
┌────────────────────────────────────────────────┐
│ ▲ ÜST BÖLGE (label start:'dan ÖNCE) │
│ Buraya define ve default yazılır. │
│ Girintisiz, satır başından başla. │
│ │
│ define d = Character("Defne") │
│ default ruh_hali = 0 │
│ │
├────────────────────────────────────────────────┤
│ ▼ ALT BÖLGE (label start:'dan SONRA) │
│ Buraya hikaye yazılır. │
│ Her satır 4 boşluk girintili. │
│ │
│ label start: │
│ d "Günaydın!" │
│ $ ruh_hali += 1 │
│ │
└────────────────────────────────────────────────┘
define = Etiket
Bir şeye isim takıyorsun. O isim oyun boyunca hep aynı kalıyor.
Gerçek hayattan örnekler:
- Defne'nin adı hep "Defne", değişmez
- Oyunun adı hep "Kahve Molası", değişmez
- Defne'nin isim rengi hep yeşil, değişmez
# ▲ ÜST BÖLGEYE yaz (label start:'dan önce)
define d = Character("Defne", color="#c8ffc8")
define b = Character("Ben", color="#c8c8ff")
default = Sayaç / Bayrak
Başlangıç değeri veriyorsun. Oyuncu seçim yaptıkça bu değer değişiyor.
Gerçek hayattan örnekler:
- Ruh hali: başta 0, Lila ile konuşunca +1, yalnız kalınca -1
- Kahve içti mi: başta Hayır, sade seçerse Evet'e döner
- Bölüm numarası: başta 1, ilerledikçe 2, 3, 4...
# ▲ ÜST BÖLGEYE yaz (define'ların hemen altına)
default ruh_hali = 0 # sayı: artıp azalacak
default sade_icti = False # bayrak: True veya False
default bolum = 1 # sayı: ilerledikçe artacak
Minik örneklerle fark:
define: Defne'nin adı oyun boyunca hep "Defne":
define d = Character("Defne")
# oyun boyunca d hep "Defne" kalır
# kimse bunu değiştiremez
default: Ruh hali başta 0, sonra değişir:
default ruh_hali = 0
# oyuncu "Lila ile konuş" seçerse:
# $ ruh_hali += 1 → artık 1
# oyuncu "yalnız kal" seçerse:
# $ ruh_hali -= 1 → artık -1
Hangisini ne zaman kullanırım?
| Durum | define | default |
|---|---|---|
| Karakter tanımı (isim, renk) | ✔ | ✘ |
| Oyuncunun bir şeyi seçip seçmediği | ✘ | ✔ |
| Puan / sayaç (sevgi, korku, ruh hali) | ✘ | ✔ |
| Oyun adı, config ayarı | ✔ | ✘ |
Oyun içinde $ ile değişecek her şey |
✘ | ✔ |
define ile tanımlamak. Oyuncu kayıt yükleyince değer sıfırlanır, seçimler kaybolur. Basit kural: oyun içinde değişecek mi? Evet → default. Hayır → define.default ile tanımladığın bir değişkeni hikaye sırasında değiştirmek istediğinde satırın başına $ koyarsın. $ = "bu değeri güncelle" demek. Sadece alt bölgede (label'ın içinde, 4 boşluk girintili) kullanılır:
label start:
# oyuncu "Lila ile konuş" seçti, ruh hali artıyor:
$ ruh_hali += 1
# oyuncu sade kahve seçti, bayrağı True yap:
$ sade_icti = True
Metin Etiketleri (Text Tags)
Diyalog metninin içine özel etiketler koyarak yazıyı kalın, eğik, renkli yapabilir veya metnin nasıl gösterileceğini kontrol edebilirsin. Süslü parantez { } içinde yazılırlar.
Biçimlendirme Etiketleri
Metnin görünümünü değiştiren etiketler:
d "{b}Bu kalın metin.{/b} Bu normal."
d "{i}Bu eğik metin.{/i}"
d "{u}Altı çizili metin.{/u}"
d "{s}Üstü çizili metin.{/s}"
d "{color=#ff0000}Kırmızı metin.{/color}"
d "{size=+10}Daha büyük{/size} ve {size=-5}daha küçük.{/size}"
{b}...{/b}
Kalın metin
▾
{b}...{/b}d "{b}Bu kelime kalın.{/b} Bu normal."
d "{b}Tüm cümle kalın olur.{/b}"
d "{b}{i}Kalın ve eğik birlikte.{/i}{/b}"
Ren'Py'de {b} tek kalınlık seviyesi verir, CSS gibi font-weight:900 yapılamaz. Daha kalın istersen fontu değiştirmen gerekir (gui.rpy'de bold varyantı olan font seç). İç içe etiketlerle kombine edilebilir.
{i}...{/i}
Eğik metin
▾
{i}...{/i}d "{i}İç ses veya düşünce.{/i}"
n "{i}Rüzgar hafifçe esiyordu.{/i}"
d "{i}{color=#aaaacc}Sessiz iç monolog.{/color}{/i}"
Italic font yüklü değilse Ren'Py sentetik eğiklik uygular. Daha iyi sonuç için gui.rpy'de gui.text_font'un italic varyantını ayarla. Renk + eğik kombinasyonu iç ses sahnelerinde çok etkili.
{u}...{/u}
Altı çizili metin
▾
{u}...{/u}d "{u}Önemli not:{/u} bunu unutma."
d "{color=#4ecdc4}{u}tıklanabilir gibi{/u}{/color} görünür."
Çizgi kalınlığı veya stili ayarlanamaz, Ren'Py tek seviye altı çizgi çizer. Renkle birlikte kullanırsan "link" etkisi yaratır. Oyuncuya tıklanabilir bir şey olduğunu ima etmek için {color}{u}...{/u}{/color} kombinasyonu etkili.
{s}...{/s}
Üstü çizili metin
▾
{s}...{/s}d "Fiyat: {s}50 TL{/s} 30 TL!"
d "{s}Bunu söylememeliydim.{/s} Şey, yani..."
d "{s}{color=#888}eski plan{/color}{/s} → yeni plan"
Çizgi kalınlığı ve rengi ayarlanamaz, metin rengiyle aynı olur. Soluk renk + üstü çizili kombinasyonu "iptal edilmiş" hissi güçlendirir. Karakter pişmanlığı, fiyat karşılaştırması veya düzeltme için ideal.
{color=#hex}...{/color}
Renkli metin. Hex renk kodu kullan.
▾
{color=#hex}...{/color}d "{color=#ff0000}Tehlike!{/color} Buradan kaç."
d "{color=#4ecdc4}Sakin ol.{/color} Her şey yolunda."
d "{color=#ffd166}Altın{/color} anahtar bulundu."
Hex renk kodu: #ff0000 = kırmızı, #4ecdc4 = teal, #ffd166 = altın. 8 haneli hex (#ff000080) ile yarı saydam renk de verebilirsin, son 2 hane saydamlık (00=şeffaf, FF=opak).
{size=±N}...{/size}
Büyük veya küçük metin. +10 / -5 gibi.
▾
{size=±N}...{/size}+10 / -5 gibi.d "{size=+15}BAĞIRMA!{/size}"
d "{size=-4}(fısıldayarak) duydun mu?{/size}"
d "{size=+8}Önemli:{/size} kapıyı {size=-3}sessizce{/size} kapat."
+N piksel ekler, -N çıkarır. Varsayılan font ~22px ise +15 = 37px, -8 = 14px olur. +25 üstü diyalog kutusunu taşırabilir. Mutlak boyut da verebilirsin: {size=40} direkt 40px yapar (+ veya - olmadan).
{outlinecolor=#hex}...{/outlinecolor}
Metnin dış çizgi rengini değiştirir.
▾
{outlinecolor=#hex}...{/outlinecolor}# Önce gui.rpy'de outline tanımla (yoksa etiket çalışmaz):
define gui.text_outlines = [(2, "#000000", 0, 0)]
# Sonra script.rpy'de kullan:
d "{outlinecolor=#ff0000}Tehlike!{/outlinecolor} Normal metin."
d "{outlinecolor=#ffd166}Altın parıltı.{/outlinecolor}"
Önce Özelleştirme bölümünden gui.text_outlines tanımla. Tanımsızsa etiket hiçbir şey yapmaz. Kalınlık bu etiketle değiştirilemez, gui.rpy'deki (kalınlık, renk, x, y) listesinden gelir. Kalınlığı artırmak için: [(4, "#000", 0, 0)] gibi ilk sayıyı büyüt. Birden fazla katman ekleyerek glow efekti de yapılabilir.
{alpha=X}...{/alpha}
Yarı saydam metin. 0.0–1.0 arası.
▾
{alpha=X}...{/alpha}0.0–1.0 arası.d "Bu net. {alpha=0.3}Bu çok soluk.{/alpha}"
d "{alpha=0.5}Hayalet gibi konuşuyorum...{/alpha}"
d "{alpha=0.0}Görünmez metin (ama yer kaplar).{/alpha}"
0.0 = görünmez, 0.5 = yarı saydam, 1.0 = tam opak. {alpha=*0.5} ile mevcut saydamlığı yarıya düşürebilirsin (çarpma modu). İç içe kullanılabilir: {alpha=0.6}{color=#ff0}soluk altın{/color}{/alpha}. Hayalet karakter, solma, gizli ipucu veya "okunamayan metin" efekti için ideal.
# Outline ve saydamlık örnekleri
d "{outlinecolor=#ff0000}Tehlike!{/outlinecolor} Sakin ol."
d "Bu {alpha=0.3}soluk{/alpha} ama bu net."
{outlinecolor} kullanabilmen için önce gui.rpy'de veya Character tanımında outline ayarlamış olman gerekir. Ayar yoksa bu etiket görünür bir şey yapmaz. Detaylar Özelleştirme > Metin Dış Çizgisi bölümünde.Akış Kontrol Etiketleri
Metnin ekranda nasıl ve ne zaman gösterileceğini kontrol eden etiketler. Bunlar dramatik anlatım için çok önemli:
# Oyuncu tıklayana kadar bekle, sonra devam et
d "Kapıyı açtım ve...{w} içeride kimse yoktu."
# Otomatik 2 saniye bekle, sonra devam et
d "3...{w=1.0}2...{w=1.0}1...{w=1.0}Başla!"
# Satır sonu + tıklama bekle (sayfa gibi)
d "İlk paragraf.{p}İkinci paragraf yeni satırda."
# Tıklama beklemeden anında göster (NPC acele konuşsun)
d "Dur!{nw}"
d "Dur! Beni dinle!"
# Önceki metin görünmeden direkt buradan başla
d "Bla bla uzun metin...{fast}ama sadece burayı görürsün."
{w}
Metin ortasında tıklama bekler, sonra aynı satırda devam eder. Gerilim anları için birebir.
{w=N}
N saniye bekler, tıklamaya gerek kalmadan devam eder. Geri sayım efekti.
{p}
Tıklama bekler, sonra eski metni silip yeni satırdan devam eder. Paragraf geçişi.
{nw}
"No wait": tıklama beklemeden hemen sonraki diyaloğa geçer. Hızlı kesme efekti.
{fast}
Bu etiketin öncesindeki her şey anında gösterilir, yazma animasyonu atlanır.
{cps=N}
Metnin yazılma hızını değiştirir. {cps=5} = saniyede 5 karakter (yavaş, fısıltı). {cps=*3} = varsayılanın 3 katı.
{nw} ile Metin Birleştirme
Bir karakter cümlenin ortasında kesilip devam etsin istersen {nw} ile {fast} birlikte kullanılır:
d "Ben aslında...{nw}"
d "Ben aslında...{fast} seni çok seviyorum!"
İlk satır ekranda "Ben aslında..." gösterir ve hemen ikinci satıra geçer. İkinci satırda {fast}'tan önceki kısım anında yazılır (tekrar gösterilmez), sadece "seni çok seviyorum!" yeni metin olarak eklenir. Sonuç: oyuncu kesintisiz bir cümle görür.
Değişkenleri Metin İçinde Gösterme
Köşeli parantez [ ] ile değişken değerlerini diyaloğun içine yerleştir:
default oyuncu_adi = "Oyuncu"
label start:
$ oyuncu_adi = renpy.input("Adın ne?")
d "Merhaba, [oyuncu_adi]! Hoş geldin."
d "Bugün kahve [oyuncu_adi] ikramı!"
[oyuncu_adi] çalışma anında değişkenin gerçek değeriyle değiştirilir. Oyuncu "Emre" yazdıysa ekranda "Merhaba, Emre!" görünür.
Dosya Yapısı (File Structure)
Ren'Py projesinin tüm dosyaları game/ klasörünün içinde yaşar: senaryonun, görsellerini, müziklerini, arayüz ayarlarını, her şey burada. Hangi dosyanın ne işe yaradığını bilirsen "bunu nereye koyacağım?" sorusu kalmaz. İşte yapı:
En çok dokunacağın dosyalar:
script.rpy: tüm senaryonimages/: görsellerini buraya koyaudio/: müzik ve sesleri buraya koygui.rpy: görünümü özelleştirmek içinoptions.rpy: oyun başlığı, sürümü vs.
script.rpy dışında yeni .rpy dosyaları oluşturabilirsin (mesela bolum2.rpy). Ren'Py hepsini otomatik yükler. Label'lar dosyalar arası çalışır. bolum2.rpy'daki bir label'a jump yazman yeterli.⚠
.rpy'yi silersen yanındaki .rpyc'yi de sil, yoksa Ren'Py silinen dosyayı hâlâ çalıştırmaya çalışır.
Ekranlar (Screens & Screen Language)
Ren'Py'de oyuncunun gördüğü her arayüz parçası bir ekran (screen). Diyalog kutusu, ana menü, kayıt ekranı, seçenek menüsü, hepsi birer screen. Ren'Py bunları screens.rpy dosyasında tanımlar.
Ekran Nedir? (What is a Screen?)
Bir screen, ekranda gösterilen UI elementlerinin tarifnamesi. scene, show ve hide komutlarıyla gösterilir, ama asıl güçleri screen deyimiyle kendi ekranlarını yazmanda.
script.rpy (label, say, menu). Arayüz tasarımı → screens.rpy (screen, text, button, vbox). İkisi birbirinden bağımsız çalışır.
Yerleşik Ekranlar (Built-in Screens)
Ren'Py yeni projede bu ekranları otomatik oluşturur. Hepsini screens.rpy içinde bulursun:
say
Diyalog kutusu. Karakter adı + konuşma metni gösterir.
choice
Seçenek menüsü. menu: komutuyla tetiklenir.
main_menu
Oyun açılınca ilk gelen ekran: Yeni Oyun, Devam Et, Ayarlar.
game_menu
Oyun içi menü: Kaydet, Yükle, Geçmiş, Ayarlar.
save / load
Kayıt ve yükleme slotları.
preferences
Ses, metin hızı, tam ekran gibi ayarlar.
nvl
Tam sayfa metin modu (roman tarzı anlatım).
notify
Ekranın üstünde kısa bildirim mesajı.
Basit Ekran Yazımı (Screen Language Basics)
Kendi ekranını yazmak için screen deyimini kullan. İçine text, textbutton, vbox, hbox, imagebutton gibi elementler koyarsın:
screen bilgi_ekrani():
vbox:
xalign 0.5
yalign 0.5
spacing 20
text "Hoş geldin!" size 40
text "Bu senin ilk ekranın."
textbutton "Kapat" action Hide("bilgi_ekrani")
Ekranı göstermek ve gizlemek için:
label start:
show screen bilgi_ekrani
"Ekran göründü."
hide screen bilgi_ekrani
"Ekran kapandı."
Screen Elementleri (Screen Displayables)
text
Ekrana metin yazar. text "Merhaba" size 30 color "#fff"
textbutton
Tıklanabilir metin. textbutton "Başla" action Start()
imagebutton
Tıklanabilir görsel. Idle/hover/selected PNG'leri alır.
vbox / hbox
Dikey / yatay kutu. Elementleri alt alta veya yan yana dizer.
frame
Arka planlı kutu. İçine başka elementler koyarsın.
bar / vbar
Yatay/dikey çubuk. Ses seviyesi, HP barı gibi.
add
Ekrana görsel ekler. add "logo.png" xalign 0.5
timer
Zamanlayıcı. Belirli süre sonra action tetikler.
Screen Actions (Eylemler)
Butonlara ve elementlere bağlanan aksiyonlar. En çok kullanılanlar:
# Sayfalar arası geçiş
textbutton "Yeni Oyun" action Start()
textbutton "Devam Et" action ShowMenu("load")
textbutton "Ayarlar" action ShowMenu("preferences")
textbutton "Çıkış" action Quit(confirm=True)
# Ekranları aç/kapat
textbutton "Göster" action Show("bilgi_ekrani")
textbutton "Kapat" action Hide("bilgi_ekrani")
# Değişken değiştir
textbutton "Kabul Et" action SetVariable("kabul", True)
textbutton "Sesi Aç" action SetMute("music", False)
screens.rpy'yi aç ve ilgili screen bloğunu düzenle. Sıfırdan yazmana gerek yok, mevcut olanı özelleştir.
Özelleştirme (GUI Customization)
Ren'Py'nin varsayılan arayüzü her projede aynı görünür: gri butonlar, standart font, düz diyalog kutusu. Oyununa kimlik kazandırmak için arayüzü özelleştirirsin: renkler, fontlar, diyalog kutusu, arka plan görselleri, buton tasarımları. Tek bir gui.rpy dosyasından neredeyse her şeyi kontrol edebilirsin.
Bu bölümde şunları değiştirmeyi öğreneceksin:
🖼 Arka Plan
Ana menü ve oyun içi arka plan görselleri
💬 Diyalog Kutusu
Şekil, boyut, konum, PNG veya kod tabanlı
🏷 İsim Kutusu
Karakter adı alanı + her karaktere ayrı renk
🖱 Butonlar
Normal, hover, seçili durum görselleri
🎨 Renkler & Font
Tüm metin, menü, vurgu renkleri + özel font
⌨ Geliştirici Kısayolları
Shift+D, Shift+R, Shift+C ve diğerleri
Ren'Py yeni proje oluşturduğunda game/gui/ klasörüne otomatik PNG dosyaları koyar. Bu PNG'leri herhangi bir görsel editörle (Photoshop, GIMP, Figma) değiştirince arayüzün her parçası değişir. gui.rpy'daki ayarlarla renkler, fontlar ve boyutlar ayarlanır.
game/images/→ arkaplan ve karakter görsellerigame/gui/→ arayüz görselleri (diyalog kutusu, butonlar, menü arka planı)game/audio/→ müzik ve ses efektlerigame/veyagame/fonts/→ özel font dosyaları (.ttf, .otf)
VN Arayüzü: Hangi Parça Nereden Geliyor?
gui/namebox.png: karakter adı kutusugui/textbox.png: diyalog alanıgui/button/: hızlı menü butonlarıgui/main_menu.png: arka plangui/ Klasör Haritası
Proje oluşturulduğunda otomatik gelen dosyalar, bunları değiştirerek arayüzü şekillendir:
gui/ klasörünü okur.Pencere Başlığı ve Simgesi
options.rpy dosyasında:
define config.name = "Kahve Hikayesi" # Pencere başlığında görünür
define config.version = "1.0" # Kayıt dosyası adında kullanılır
Görev çubuğu simgesini değiştirmek için gui/window_icon.png dosyasını istediğin simgeyle değiştir.
Renkler
Tüm menüler, butonlar ve metinlerin rengi buradan yönetilir. Tek bir değeri değiştirince arayüzün her yerinde güncellenir:
define gui.accent_color = '#e84855' # Vurgu rengi (buton çerçeveleri, başlıklar)
define gui.idle_color = '#888888' # Pasif menü yazıları
define gui.hover_color = '#ffffff' # Buton üzerine gelinince
define gui.selected_color = '#e84855' # Seçili öğe (radio, checkbox vb.)
define gui.text_color = '#ffffff' # Diyalog metin rengi
define gui.interface_text_color = '#ffffff' # Menü arayüz yazıları
'#e84855'. Saydamlık eklemek istersen sonuna 2 hane daha ekle: '#e8485580'. Son iki hane saydamlığı belirler: 00 = tamamen şeffaf, FF = tamamen opak.
Font
Kendi fontunu eklemek 2 adım:
Font dosyasını (.ttf veya .otf) game/ klasörüne at, ister direkt içine, ister game/fonts/ alt klasörüne.
gui.rpy'de sadece dosya adını yaz (alt klasördeyse klasörüyle birlikte).
Örnek: game/fonts/Orbitron.ttf → gui.rpy'ye "fonts/Orbitron.ttf" yaz.
define gui.text_font = "NotoSans.ttf" # Diyalog metin fontu
define gui.name_text_font = "NotoSans.ttf" # Karakter adı fontu
define gui.interface_font = "NotoSans.ttf" # Menü ve arayüz fontu
define gui.text_size = 22 # Diyalog yazı boyutu (piksel)
define gui.name_text_size = 30 # Karakter adı boyutu
Metin Dış Çizgisi (Outline)
Diyalog metninin etrafına dış çizgi ekler, arka plan ne olursa olsun yazı okunur kalır. Format: (kalınlık, renk, x_offset, y_offset)
# gui.rpy: diyalog metni dış çizgisi
define gui.text_outlines = [(2, "#000000", 0, 0)] # 2px siyah çizgi, ortalı
# Karakter adı dış çizgisi
define gui.name_text_outlines = [(2, "#000000", 0, 0)]
# Menü yazıları dış çizgisi
define gui.interface_text_outlines = [(1, "#000000", 0, 0)]
# Glow efekti: birden fazla katman üst üste
define gui.text_outlines = [
(4, "#0044ff44", 0, 0), # Dışta: mavi parlama (hafif saydam)
(2, "#0088ffaa", 0, 0), # Ortada: daha yoğun mavi
(1, "#ffffff", 0, 0), # İçte: beyaz ince çizgi
]
kalınlık: piksel. 1–2 okunabilirlik için, 4+ glow efekti için.renk: hex, sonuna 2 hane saydamlık eklenebilir (#00000088 = %50 opak siyah).x_offset / y_offset: çizgiyi kaydır. 2, 2 = sağ-alt gölge efekti.
Karakter Bazında Outline
Her karakterin isim ve diyalog metnine ayrı outline verebilirsin. gui.rpy'deki genel ayarı geçersiz kılar:
define d = Character('Defne',
color="#c8ffc8",
who_outlines=[(2, "#005500", 0, 0)], # Karakter adının çizgisi
what_outlines=[(1, "#000000", 0, 0)] # Diyalog metninin çizgisi
)
who_outlines = karakter adının çevresindeki çizgi. what_outlines = konuşma metninin çevresindeki çizgi. Tanımlamadığın karakterler gui.rpy'deki genel ayarı kullanmaya devam eder.Metin İçinde Outline Rengi Değiştirme
Diyaloğun belirli bir kelimesine farklı outline rengi vermek için {outlinecolor} text tag'ini kullan:
d "{outlinecolor=#ff0000}Tehlike!{/outlinecolor} Sakin ol, panik yapma."
# Buton veya arayüz metninde de çalışır
d "Bu {outlinecolor=#ffaa00}önemli{/outlinecolor} bir karar."
{outlinecolor} sadece rengi değiştirir, kalınlık gui.rpy'deki veya Character tanımındaki ayardan gelir. Outline tanımlı değilse bu tag görünür bir etki yaratmaz, önce outline ayarla.Diyalog Kutusu: Şekil, Boyut, Konum
define gui.textbox_height = 185 # Kutu yüksekliği (piksel)
define gui.textbox_yalign = 1.0 # Konum: 1.0 = en alt, 0.5 = ortada, 0.0 = en üst
Diyalog kutusunu değiştirmenin iki yolu var, şekle göre birini seç:
Yöntem 1: PNG
Figma / Photoshop'ta istediğin şekli çiz (köşegen kesik, oval, konuşma balonu…), saydam PNG olarak kaydet, mevcut dosyanın üzerine at. Ren'Py şeffaf kısımları göstermez.
Yöntem 2: Kod (yuvarlatılmış köşe)
PNG olmadan, direkt gui.rpy'e yaz. Sadece köşe yarıçapı ayarlanabilir, karmaşık şekil yok ama renk tek satırda değişir.
# gui.rpy: Yöntem 2: yuvarlatılmış köşe (12 = köşe yarıçapı piksel)
style window:
background Frame(RoundedRectangle("#0a0a1aee", 12), Borders(20, 16, 20, 16))
xpadding 24
ypadding 16
textbox.png dosyasını sil, yoksa PNG öncelik alır.
İsim Kutusu
Karakter adının göründüğü kutunun görseli namebox.png'dan gelir. PNG'yi değiştirerek şeklini, gui.rpy'de aşağıdaki değerleri değiştirerek boyutunu ayarlarsın:
define gui.namebox_width = None # None = metne göre otomatik genişlik
define gui.namebox_height = None # None = otomatik yükseklik
define gui.namebox_borders = Borders(5, 5, 5, 5) # İç boşluk: sol, üst, sağ, alt
Arka Plan Görselleri
game/gui/main_menu.png
Oyun açılınca çıkan ilk ekranın arka planı. Logo ve butonlar bunun üstüne bindirilir.
game/gui/game_menu.png
Kaydet, Yükle, Ayarlar, Geçmiş ekranlarının arka planı. Genellikle koyu veya bulanık görsel kullanılır, menü yazıları okunabilsin diye.
Buton Görünümleri
Menü butonları (Yeni Oyun, Kaydet, Yükle vb.) dört durumda farklı görüntü gösterebilir. PNG'leri bu klasöre koy:
normal durum
üzerine gelince
seçili durum
Karakter Adı Rengi
Her karakterin ekranda görünen adı farklı renkte olabilir, diyalog kutusunda kimin konuştuğunu renkle ayırt etmek için kullanılır:
define d = Character('Defne', color="#c8ffc8") # Açık yeşil
define e = Character('Emre', color="#c8c8ff") # Açık mavi
define n = Character('Anlatıcı', color="#ffd166") # Sarı/altın
Bu renk sadece namebox'taki isim metnine uygulanır. Diyalog metninin rengini değiştirmez.
Geliştirici Kısayolları
Oyun çalışırken bunları kullanabilirsin, geliştirici modunda aktif olur (yeni projede varsayılan olarak açık):
Shift+D
Geliştirici menüsü. Reload, stil editörü, diğer araçlara buradan ulaşırsın.
Shift+R
Script'leri yeniden yükle. Oyunu kapatmadan yaptığın değişikliği anında görürsün.
Shift+I
Stil inspector. Fareyi bir elementin üstüne götür, hangi stil kuralının ne yaptığını gösterir.
Shift+E
Şu an bulunduğun sahnenin script dosyasını editörde açar.
Shift+C
Python konsolu. Canlı Python kodu yazarsın, değişken değerini kontrol etmek için ideal.
Shift+O
Rollback (geri sarma) iznini açıp kapatır. Test sırasında belirli bir sahneye geri dönmek için.
options.rpy'de config.developer = True satırının aktif olduğuna bak.Bonus: NVL Modu: Tam Ekran Metin
Klasik VN diyalog kutusuna alternatif olarak NVL modu var: metin ekranın tamamını kaplar, roman gibi paragraflar halinde ilerler:
# NVL karakter tanımı:
define anlatici = Character(None, kind=nvl)
define d_nvl = Character("Defne", kind=nvl)
# Kullanımı:
anlatici "Sabah sisi çoktan kalkmıştı."
anlatici "Kahvenin buğusu pencerede iz bırakıyordu."
d_nvl "Günaydın."
nvl clear # Ekranı temizle, yeni sayfaya geç
kind=nvl karakteri NVL moduna geçirir. nvl clear ile sayfayı temizlersin. Normal VN diyaloğuna dönmek istersen kind=adv karakter kullan.gui/ klasöründeki dosyaları fabrika ayarına sıfırlar. Özelleştirdiğin dosyaların üzerine yazar, dikkatli kullan, önce yedek al.Seçenek Menüsü (Choice Screen)
Oyuncuya sunulan seçenekler de özelleştirilebilir. Seçenek butonlarının iki durumu var:
# gui.rpy: seçenek buton boyutları
define gui.choice_button_width = 1185 # Buton genişliği (piksel)
define gui.choice_button_height = None # None = metne göre otomatik
define gui.choice_button_text_font = gui.text_font
define gui.choice_button_text_size = gui.text_size
Overlay: Menü Üstü Katman
Ana menü ve oyun menüsünün arka plan görseli üstüne yarı saydam bir katman bindirilir. Böylece butonlar okunabilir kalır:
Kayıt ve Yükleme Ekranı
Kayıt slotlarının görünümü de PNG ile değiştirilir. Her slot ekran görüntüsü (thumbnail) ve bilgi içerir:
# gui.rpy: kayıt slotu ayarları
define gui.slot_button_width = 414 # Slot genişliği
define gui.slot_button_height = 309 # Slot yüksekliği
define config.thumbnail_width = 384 # Ekran görüntüsü genişliği
define config.thumbnail_height = 216 # Ekran görüntüsü yüksekliği
define gui.file_slot_cols = 3 # Satır başına slot sayısı
define gui.file_slot_rows = 2 # Sayfa başına satır sayısı
Slider ve Scrollbar
Ses seviyesi, metin hızı gibi ayarlar slider ile, geçmiş panel ve uzun listeler scrollbar ile kaydırılır. İkisi de PNG ile özelleştirilir:
Skip ve Bildirim Göstergesi
Oyuncu diyalogları atladığında veya ekranda bir bildirim çıkması gerektiğinde bu görseller kullanılır:
# Script'ten bildirim göndermek:
$ renpy.notify("Oyun kaydedildi!")
# Başarım kilidi açıldığında:
$ renpy.notify("🏆 Başarım: İlk Kahve")
Onay Ekranı (Confirm)
Oyundan çıkma, yeni oyun başlatma gibi kritik işlemlerde açılan "Emin misin?" penceresi:
gui/overlay/confirm.png ekranı karartır, gui/frame.png ise onay kutusunun çerçevesini çizer. İkisini de değiştirebilirsin.Borders Sistemi: PNG'leri Esnetmeden Ölçekle
Ren'Py, buton ve kutu PNG'lerini Borders ile ölçekler: köşeler sabit kalır, kenarlar uzar. Bu sayede tek PNG'yle her boyutta buton yapılır:
# Borders(sol, üst, sağ, alt): köşelerin piksel boyutu
define gui.frame_borders = Borders(25, 5, 25, 5)
# Kullanımı: Frame ile birlikte
style confirm_frame:
background Frame("gui/frame.png", gui.frame_borders)
gui.rpy ayarlarının tam listesi için: Ren'Py GUI Customization Guide (resmi dokümantasyon, İngilizce).
Yayınlama (Build & Distribution)
Oyunun hazır, ama şu an sadece senin bilgisayarında çalışıyor. Yayınlama, projeyi başkalarının indirebileceği bir pakete dönüştürme işlemi. Ren'Py tek tuşla Windows, Mac, Linux ve Android için dosya oluşturur. Bu dosyayı itch.io gibi platformlara yükleyince herkes oynayabilir.
Hata kontrolü: Launcher'da "Check Script (Lint)" tıkla. Tüm dosyalardaki hataları bulur.
Build: Launcher'da "Build Distributions" tıkla. Hangi platformlar için çıkaracağını seç (Windows, Mac, Linux, Android). Ren'Py zip/exe dosyalarını oluşturur.
Test et: Çıkan dosyayı başka bir bilgisayarda veya başka birinde dene. Her şeyi baştan sona oyna.
Yayınla: itch.io en popüler indie oyun platformu. Ücretsiz hesap aç, oyununu yükle, sayfanı düzenle, yayınla.
options.rpy dosyasında build.classify satırları hangi dosyaların build'e dahil edileceğini belirler. Varsayılanlar çoğu proje için yeterli.Şimdi Ne Yapmalıyım?
- Launcher'daki "Tutorial" oyununu oyna, daha fazla özellik öğrenirsin
- GUI Customization Guide: arayüzü tamamen özelleştir
- Lemma Soft Forums: topluluk, yardım, kaynak paylaşımları
- Ren'Py Dokümantasyonu: resmi rehber (İngilizce)
Topluluk Kaynakları (Community & Plugins)
Ren'Py'nin en güçlü yanlarından biri kocaman bir topluluğu. Yüzlerce geliştirici ücretsiz efektler, arayüz şablonları, mini oyun motorları ve araçlar paylaşıyor.
Aşağıda 20 adet kurulu kütüphane kod örnekleriyle anlatılıyor.
Nerede Takılırsan Nereye Sor?
Lemma Soft Forums Ana Hub
Ren'Py'nin resmi forum topluluğu. Yıllarca birikmiş soru-cevap arşivi, Cookbook (hazır kod örnekleri) ve duyurular burada. İlk başvuru noktası.
Ren'Py Discord Resmi
Gerçek zamanlı yardım. #help kanalında sorunu yaz, dakikalar içinde yanıt. Motoru geliştiren Tom'un bizzat katıldığı kanal.
r/RenPy Reddit
Yapılan oyunlar ve sorun çözme karışık. "Bunu nasıl yaptım" paylaşımları görmek veya bir şey sormak için iyi yer, daha samimi, daha az teknik.
itch.io: Araçlar Üretim
Arayüz temaları, görsel efektler, başarım sistemi, görev takibi gibi hazır araçlar var. Çoğu ücretsiz: indir, game/ klasörüne at, çalışır.
Eklenti Nasıl Kurulur?
.rpy Dosyası Kopyala
Çoğu eklenti bu. GitHub'dan .rpy dosyasını indir, game/ klasörüne at. Ren'Py otomatik tanır. Bitti.
Klasör Kopyala
Büyük eklentiler birden fazla dosya içerir. Tüm klasörü game/libs/ altına koy.
Harici Araç
VS Code eklentisi gibi şeyler Ren'Py'nin içine değil, bilgisayarına kurulur.
.rpy dosyalarından önce yüklenir. 3. parti kütüphaneleri buraya koy, kendi kodunla karışmaz.gui.rpy, options.rpy, screens.rpy, script.rpy dosyaları kopyalanmaz, bunlar demo dosyalarıdır.Mod Nasıl Kurulur?
GitHub sayfasını aç. Kart başlığındaki GitHub ↗ linkine tıkla. Repo açılır.
Dosyayı indir. Repoda .rpy uzantılı dosyayı bul ve tıkla. Açılan sayfada sağ üstte Raw butonuna bas, tarayıcıda ham kod görünür. Ctrl+S ile kaydet.
Doğru klasöre koy. İndirdiğin .rpy dosyasını şu klasöre at:
neoncross/game/libs/
(Tam yol: C:\...\neon-cross\neoncross\game\libs\)
Reload yap. Oyun açıksa Shift+D → Reload. Ren'Py modu otomatik tanır, yeniden başlatma gerekmez.
Kodu kopyala ve kullan. Aşağıdaki kartlara tıkla → kodu kopyala → script.rpy'de kullanmak istediğin sahnenin altına yapıştır.
script.rpy'ye şunu yaz:
show defne mutlu
show expression Glitch("defne mutlu") as glitch_char # bu satırı ekle
d "Ne oluyor?!"
Görsel Efektler ve Shader'lar
Glitch, CRT, hologram, ateş, parçacıklar, dalga... Oyununa sinematik atmosfer kat. Karta tıkla, kodu gör.
ChromaGlitch: Glitch Efekti GitHub ↗
DDLC tarzı RGB kayması + yatay dilim bozulması. Arka plan veya sprite'a tek satırla uygulanır.
# Arka plana glitch uygula
show expression Glitch("bg sokak") as glitch_bg
pause 0.5
scene bg sokak # Normal haline dön
# Karakter sprite'ına glitch
show expression Glitch("defne kizgin") as glitch_char
# İnce ayar: offset büyük + her seferinde farklı glitch
glitch("bg sokak", offset=60, randomkey=None)
# Sürekli titreyen glitch animasyonu
show expression animated_glitch("bg sokak", timeout_base=0.08) as glitch_bg
offsetDilim kayma miktarı (piksel). Yükseldikçe daha sert glitch. varsayılan: 30randomkeyNone = her renderda farklı görünür. Sabit değer = hep aynı glitch desenini üretir. varsayılan: otomatikchromaKromatik aberasyon (RGB kayması) açık/kapalı. varsayılan: TrueminbandheightBir dilimin minimum piksel yüksekliği. Küçük = çok ince dilimler. varsayılan: 1timeout_base(animated_glitch) Glitch titreme hızı saniye cinsinden. 0.08 = çok hızlı. varsayılan: 0.1
RGB Split: Kromatik Aberasyon GitHub ↗
Kırmızı, yeşil, mavi katmanları birbirinden kaydırır, ekran parçalanıyor gibi görünür.
# Sahneye RGB split uygula
show bg studyo at rgb_split_transform
with vpunch
d "Ne yaptın sen?!"
Wave Shader: Dalga Bozulması GitHub ↗
Sahne veya metni dalgalandırır. Gerçeklik algısının bozulduğu anlarda atmosfer kurar.
# Metin dalgalandırma (text tag)
d "{wave}Her şey dönüyor...{/wave}"
# Sahne dalga efekti (ATL ile)
show bg klub:
parallel:
function WaveShader() # Sürekli dalga: asla bitmez
parallel:
3.0 # 3 sn sonra dur
show bg klub # Normal hale dön
amplitudeDalga yüksekliği (piksel). Büyük değer = daha sert bozulma. varsayılan: 10frequencyDalga sıklığı. Yüksek = çok dalgalı, sıkışık görüntü. varsayılan: 10speedAnimasyon hızı çarpanı. 2.0 = iki kat hızlı. varsayılan: 1.0parallelWaveShader() ATL'de sürekli döngüdedir. Durdurmak için parallel + süre bloğu kullan.CRT Shader: Retro TV Efekti Gist ↗
Eski televizyon gibi tarama çizgileri ve hafif bükülme efekti. Geçmiş sahne veya eski kayıt izleme hissi verir.
# Flashback sahne: eski TV efekti
show expression CRT("bg cocukluk_evi") as crt_bg
d "{fi}O günü hatırlıyorum...{/fi}"
scene bg cocukluk_evi # Normal haline dön
SWHolo: Hologram Efekti GitHub ↗
Mavi ton + tarama çizgisi + titreşim. Karakteri "sanal varlık" gibi sunar.
# Karakter hologram olarak belirsin
show expression Holo("demir ciddi") as demir_holo
d "Demir'in hologramı belirdi."
# Renk ve yoğunluk ayarla (options.rpy'e veya script başına ekle):
define holovalues.tintcolor = "#06f" # Mavi (varsayılan)
define holovalues.totalpha = 0.9 # Genel saydamlık
define holovalues.lineheight = 4 # Tarama çizgisi kalınlığı
tintcolorHologram rengi. "#06f" = mavi, "#0f6" = yeşil, "#f06" = kırmızı. varsayılan: "#06f"totalphaHologramın genel saydamlığı. 0.0 = görünmez, 1.0 = tam opak. varsayılan: 0.9interalphaÇizgiler arası saydamlık. Düşürdükçe tarama efekti güçlenir. varsayılan: 0.75blinkingTitreşim/yanıp sönme sıklığı. 0.0 = hiç, 1.0 = sürekli. varsayılan: 0.5lineheightTarama çizgilerinin kalınlığı (piksel). varsayılan: 4
Blend Modes: Photoshop Karıştırma GitHub ↗
13 farklı katman karıştırma seçeneği. Neon ışık, gölge, renk tonu eklemek için. Photoshop'taki blend mode'ların Ren'Py versiyonu.
# Neon ışığı overlay olarak ekle
show expression Screen("neon_isik.png", "bg sokak") as lit_bg
# Karanlık sahne: multiply ile gölge
show expression Multiply("golge.png", "bg oda") as dark_bg
Outline Shader: Dış Çizgi GitHub ↗
Herhangi bir görsele renkli dış çizgi ekler. Konuşan karakteri vurgulamak için sıfır maliyet.
# Karaktere neon dış çizgi
show defne mutlu at outline(color="#ff00ff", width=3)
Doomfire: Ateş/Duman Efekti GitHub ↗
Prosedürel, parametrik ateş simülasyonu. Sahnenin altına veya üstüne katman olarak bindirilebilir.
# Sahnenin altına ateş şeridi
show expression DoomFire(1280, 200) as fire_effect
d "Stüdyo yanıyor!"
hide fire_effect # Bitince kaldır
# İnce ayar: daha küçük, daha yoğun ateş
show expression DoomFire(400, 120, fire_mult=2.0) as fire_small
widthEfektin genişliği (piksel). Sahne genişliğini (1280 veya 1920) ver. zorunluheightAteş şeridinin yüksekliği. 200 = normal alev, 400 = büyük yangın. zorunlufire_multAteş yoğunluğu çarpanı. 1.0 = normal, 2.0 = daha güçlü alev. varsayılan: 1.0KonumlandırmaAteşi ekranın altına sabitlemek için: show … at bottom veya ypos 0.8RenPyParticles: Parçacık Sistemi GitHub ↗
Özel sprite tabanlı parçacık sınıfı. Sahneye canlılık ve hava katmanı verir.
# Konfeti efekti (konser/kutlama)
show expression Particles("confetti.png") as confetti
d "Sahne patladı!"
# Duman efekti (klüp/stüdyo)
show expression Particles("smoke.png") as smoke
Arka Plan Efektleri
Fare hareketine tepki veren 3D parallax arka planlar. Statik bir sahneye derinlik ve hareket katar, oyuncunun dikkatini hikayeye çeker.
Visual novel'lerde arka planlar genelde sabit durur. Fare takipli parallax efektiyle sahneye derinlik katabilirsin: fare hareket ettikçe arka plan hafifçe kayar, eğilir ve yakınlaşır. Tek bir görsel ile 3D his yaratırsın.
Canlı Önizleme
Fareyi aşağıdaki sahnenin üzerinde gezdirin:
fareyi gezdirin
ParallaxBG — Kod & Parametreler
CDD sınıfı: fare takibi + 3D perspektif eğimi + dinamik zoom. game/parallax.rpy olarak kaydet.
Ren'Py'nin Creator-Defined Displayable (CDD) sistemiyle fare pozisyonunu takip eden özel bir displayable. Her frame'de:
- Fare pozisyonu -1..1 aralığına normalize edilir
- Lerp ile ani atlamalar önlenir
- Görsel %12 büyük render edilir (kenar görünmesin)
Matrix.rotate()ile 3D perspektif eğimi- Merkeze yakınsa zoom artar, kenarlarda azalır
init python:
class ParallaxBG(renpy.Displayable):
def __init__(self, path, shift=40, tilt=3.0, smooth=0.05, **kwargs):
super(ParallaxBG, self).__init__(**kwargs)
self.image = Image(path)
self.shift = shift # piksel cinsinden kayma miktarı
self.tilt = tilt # derece cinsinden eğim
self.smooth = smooth # lerp hızı (0-1, düşük = yumuşak)
self.sx = 0.0
self.sy = 0.0
def render(self, width, height, st, at):
mx, my = renpy.get_mouse_pos()
# Fare pozisyonunu -1..1 aralığına normalize et
nx = max(-1.0, min(1.0, (mx / max(1.0, float(width)) - 0.5) * 2.0))
ny = max(-1.0, min(1.0, (my / max(1.0, float(height)) - 0.5) * 2.0))
# Yumuşak takip (lerp)
self.sx += (nx - self.sx) * self.smooth
self.sy += (ny - self.sy) * self.smooth
# Dinamik zoom: merkez=1.12, kenar=1.08
dist = min(1.0, (self.sx ** 2 + self.sy ** 2) ** 0.5)
dyn_zoom = 1.12 - dist * 0.04
# 3D perspektif eğimi
rx = -self.sy * self.tilt
ry = self.sx * self.tilt
t = Transform(self.image,
zoom=dyn_zoom,
anchor=(0.5, 0.5),
align=(0.5, 0.5),
subpixel=True,
perspective=True,
matrixtransform=Matrix.rotate(rx, ry, 0)
)
cr = renpy.render(t, width, height, st, at)
cw, ch = cr.get_size()
ox = (width - cw) / 2.0 - self.sx * self.shift
oy = (height - ch) / 2.0 - self.sy * self.shift * 0.5
r = renpy.Render(width, height)
r.subpixel_blit(cr, (ox, oy))
renpy.redraw(self, 0)
return r
def event(self, ev, x, y, st):
return None
def visit(self):
return [self.image]
# Arka planları parallax ile tanımla
image bg kafe gunduz = ParallaxBG("images/bg/bg kafe gunduz.jpg")
image bg kafe aksam = ParallaxBG("images/bg/bg kafe aksam.jpg")
shiftFare takibinde kayma miktarı (piksel). Yüksek = daha dramatik. varsayılan: 40tilt3D perspektif eğimi (derece). 0 = eğim yok. varsayılan: 3.0smoothLerp hızı. Düşük = daha yavaş/yumuşak takip. varsayılan: 0.05script.rpy'deki scene bg kafe gunduz satırlarını değiştirmene gerek yok. parallax.rpy'deki image tanımı otomatik olarak devreye girer.Sprite Efektleri
Karakter sprite'larına nefes animasyonu ve fare parallax'ı ekleyerek sahneye canlılık kat. Ek asset gerekmez, tek sprite yeterli.
Statik bir sprite sahnede durduğunda "karton" hissi verir. İki basit efektle bunu kırabilirsin:
- Nefes animasyonu: Sprite çok hafif zoom salınımı yapar (bilinçaltı canlılık)
- Fare parallax: Arka plandan daha az kayma. BG ile karakter arasındaki hız farkı derinlik yaratır
Canlı Önizleme
Fareyi sahnenin üzerinde gezdirin, karakterin BG'den bağımsız hareket ettiğine dikkat edin:
fareyi gezdirin
shift=40 ile kayarken karakter shift=5 ile takip eder. Nefes salınımına da dikkat edin.ParallaxSprite — Kod & Parametreler
Nefes animasyonu + fare parallax CDD sınıfı. Aynı parallax.rpy dosyasına ekle.
class ParallaxSprite(renpy.Displayable):
def __init__(self, child, shift=5, breath_amount=0.004, breath_speed=0.3, **kwargs):
super(ParallaxSprite, self).__init__(**kwargs)
self.child = renpy.displayable(child)
self.shift = shift # fare kayma (BG'den çok daha az)
self.breath_amount = breath_amount # nefes genliği (%0.4)
self.breath_speed = breath_speed # nefes hızı (Hz)
self.sx = 0.0
self.sy = 0.0
self.cur_breath = 1.0
def render(self, width, height, st, at):
import math
sw = float(renpy.config.screen_width or 1920)
sh = float(renpy.config.screen_height or 1080)
mx, my = renpy.get_mouse_pos()
nx = max(-1.0, min(1.0, (mx / sw - 0.5) * 2.0))
ny = max(-1.0, min(1.0, (my / sh - 0.5) * 2.0))
self.sx += (nx - self.sx) * 0.03
self.sy += (ny - self.sy) * 0.03
# Nefes: sinüs dalgası ile yumuşak zoom salınımı
target = 1.0 + math.sin(st * 2.0 * math.pi * self.breath_speed) * self.breath_amount
self.cur_breath += (target - self.cur_breath) * 0.02
cr = renpy.render(self.child, width, height, st, at)
cw, ch = cr.get_size()
bw = cw * self.cur_breath
bh = ch * self.cur_breath
ox = self.sx * self.shift + (cw - bw) * 0.5
oy = self.sy * self.shift * 0.1 + (ch - bh)
r = renpy.Render(int(cw), int(ch))
r.subpixel_blit(cr, (ox, oy))
renpy.redraw(self, 0)
return r
def event(self, ev, x, y, st):
return None
def visit(self):
return [self.child]
# Karakter sprite'ını parallax ile tanımla
image lila normal = ParallaxSprite("images/chars/lila normal.png")
shiftFare kayma miktarı. BG'nin shift'inden çok düşük tutulmalı (derinlik farkı). varsayılan: 5breath_amountNefes zoom genliği. 0.004 = %0.4 salınım. varsayılan: 0.004breath_speedNefes hızı (Hz). 0.3 = ~7 saniye döngü. varsayılan: 0.3script.rpy'deki show lila normal: ATL satırları aynen kalır. Sadece image tanımı ParallaxSprite'a geçtiği için otomatik devreye girer.Derinlik Katmanları
Parallax'ın 3D hissettirmesi için katmanlar arası hız farkı gerekir.
Arka Plan (uzak)
shift=40 · tilt=3° · Fare yönünün tersine kayar, perspektif eğimi var
Karakter (orta)
shift=5 · Nefes animasyonu · BG'den 8x daha az kayma
Diyalog Kutusu (ön)
shift=0 · Sabit durur · Ren'Py'nin varsayılan UI katmanı
Buton Efektleri
Aura titreşimi + kılıç hamlesi + parçalanma: tek .rpy dosyasına kopyala, çalışır. Harici modül gerekmez.
Canlı Önizleme
Parlayan Buton — hover edin
Kılıç Kesme — tıklayın
Parlayan Buton
Butona sürekli neon aura titreşimi ekler. Hover'da renk kayar. Kılıç efekti olmadan sade parlama isteyenler için.
# ── parlayan_buton.rpy ── game/ klasörüne kaydet ──────────
# Aura: Pillow ile üretilmiş yumuşak gaussian glow PNG
# (Solid + blur kare görünür — PNG ile gerçek glow)
image p_aura = "images/fx/aura_glow.png"
# Sürekli titreyerek parlayan aura
transform p_aura_pulse:
alpha 0.25
linear 0.7 alpha 0.75
linear 0.7 alpha 0.25
repeat
# Buton stili (9-patch PNG ile border)
style p_buton is button:
background Frame("images/fx/btn_bg.png", 4, 4, 4, 4)
hover_background Frame("images/fx/btn_hover.png", 4, 4, 4, 4)
padding (30, 16, 30, 16)
style p_buton_text is button_text:
color "#4466bb"
hover_color "#99ccff"
outlines [(absolute(3), "#0044cc60", absolute(0), absolute(0))]
hover_outlines [(absolute(4), "#4488ffaa", absolute(0), absolute(0))]
size 26
screen parlayan_menu():
add "p_aura" at p_aura_pulse:
xalign 0.5 yalign 0.5
textbutton "YENİ OYUN":
style "p_buton"
text_style "p_buton_text"
xalign 0.5 yalign 0.5
action Start()
aura_glow.pngPillow ile üretilmiş yumuşak gaussian glow. Boyut/renk değiştirmek için generate_fx.py'yi düzenle. varsayılan: 480 × 160, mavioutlinesYazı etrafındaki ışık halesı. absolute(3) = kalınlık, #0044cc60 = renk+saydamlık. varsayılan: 3px mavi glowFrame("btn_bg.png", 4)9-patch buton arka planı. Border rengi için generate_fx.py'deki make_btn_bg()'yi düzenle. varsayılan: koyu lacivert + mavi çerçevealpha 0.25 / 0.75Aura parlamanın min ve max yoğunluğu. varsayılan: 0.25 – 0.75Kılıç Kesme Efekti
3 katmanlı kılıç (çizgi + parlama + iz) → karartma → ekran flaşı + sarsıntı → buton ikiye ayrılıp uçar.
# ── kilic_efekti.rpy ── game/ klasörüne kaydet ─────────────
# Aura: Pillow ile üretilmiş yumuşak glow PNG
image buton_aura = "images/fx/aura_glow.png"
# 3 katmanlı kılıç: beyaz çizgi + cyan parlama + mavi iz
image kilic_cizgi = Transform(Solid("#ffffff"), xsize=3000, ysize=10, rotate=-42)
image kilic_parlama = Transform(Solid("#66ddff"), xsize=3000, ysize=60, rotate=-42)
image kilic_iz = Transform(Solid("#3399ff"), xsize=3000, ysize=120, rotate=-42)
image kilic_flas = Solid("#cceeff")
image kilic_karanlik = Solid("#000000")
image parca_ust = "images/fx/parca_ust.png"
image parca_alt = "images/fx/parca_alt.png"
# Titreşen aura
transform aura_pulse:
alpha 0.25
linear 0.7 alpha 0.75
linear 0.7 alpha 0.25
repeat
# Vuruş öncesi karartma
transform karanlik_beat:
alpha 0.0
linear 0.08 alpha 0.4
linear 0.06 alpha 0.0
# Çekirdek çizgi — hızlı çapraz geçiş
transform kilic_cizgi_hamle:
alpha 1.0
xalign 0.5 yalign 0.5
xoffset -700 yoffset -500
linear 0.10 xoffset 700 yoffset 500
linear 0.08 alpha 0.0
# Parlama katmanı — hafif gecikmeli
transform kilic_parlama_hamle:
alpha 0.8
xalign 0.5 yalign 0.5
xoffset -700 yoffset -500
pause 0.02
linear 0.10 xoffset 700 yoffset 500
linear 0.12 alpha 0.0
# Dış iz — en gecikmeli, en geniş
transform kilic_iz_hamle:
alpha 0.35
xalign 0.5 yalign 0.5
xoffset -700 yoffset -500
pause 0.04
linear 0.10 xoffset 700 yoffset 500
linear 0.18 alpha 0.0
# Ekran flaşı
transform flas_efekti:
alpha 0.0
pause 0.08
linear 0.03 alpha 0.9
linear 0.5 alpha 0.0
# Ekran sarsıntısı
transform ekran_sarsinma:
xoffset 0 yoffset 0
easein 0.03 xoffset 14 yoffset -10
easein 0.03 xoffset -12 yoffset 8
easein 0.03 xoffset 8 yoffset -6
easein 0.03 xoffset -5 yoffset 3
easein 0.03 xoffset 0 yoffset 0
# Parçalanma
transform parca_ust_hareket:
yoffset 0 alpha 1.0
pause 0.12
parallel:
easein 0.5 yoffset -500
parallel:
linear 0.35 alpha 0.0
transform parca_alt_hareket:
yoffset 0 alpha 1.0
pause 0.12
parallel:
easein 0.5 yoffset 500
parallel:
linear 0.35 alpha 0.0
# Stil (9-patch PNG ile border + text glow)
style k_buton is button:
background Frame("images/fx/btn_bg.png", 4, 4, 4, 4)
hover_background Frame("images/fx/btn_hover.png", 4, 4, 4, 4)
padding (30, 16, 30, 16)
style k_buton_text is button_text:
color "#445599"
hover_color "#88bbff"
outlines [(absolute(3), "#0044cc60", absolute(0), absolute(0))]
hover_outlines [(absolute(4), "#4488ffaa", absolute(0), absolute(0))]
size 26
screen menu_aktif():
add "buton_aura" at aura_pulse:
xalign 0.5 yalign 0.5
textbutton "YENİ OYUN":
style "k_buton"
text_style "k_buton_text"
xalign 0.5 yalign 0.5
action Jump("kilic_efekti_oynat")
screen menu_kesilmis():
add "parca_ust" at parca_ust_hareket:
xalign 0.5 yalign 0.5
add "parca_alt" at parca_alt_hareket:
xalign 0.5 yalign 0.5
label kilic_efekti_oynat:
hide screen menu_aktif
show kilic_karanlik at karanlik_beat
pause 0.06
show kilic_iz at kilic_iz_hamle
show kilic_parlama at kilic_parlama_hamle
show kilic_cizgi at kilic_cizgi_hamle
show kilic_flas at flas_efekti
show screen menu_kesilmis
show bg kafe gunduz at ekran_sarsinma
pause 1.2
hide screen menu_kesilmis
hide kilic_cizgi
hide kilic_parlama
hide kilic_iz
hide kilic_flas
hide kilic_karanlik
jump start # ← kendi label'ınla değiştir
kilic_cizgi / parlama / iz3 katman: beyaz çizgi (10px) + cyan parlama (60px) + mavi iz (120px). Renk/kalınlık ayarlanabilir. varsayılan: #fff / #66ddff / #3399ffrotate -42Kılıç açısı. -30 = sığ hamle, -45 = dik çapraz. Tüm kilic_* image'larda aynı değer. varsayılan: -42linear 0.10Kılıç geçiş süresi. 0.06 = çok hızlı, 0.15 = yavaş. 3 katman 0.02s arayla gelir. varsayılan: 0.10ekran_sarsinmaVuruş sonrası ekran sarsıntısı. easein 0.03 × 5 kare. Offset değerlerini azalt/artır. varsayılan: ±14pxjump startEfekt sonrası atlanacak label. jump ana_menu veya Start() ile değiştir.
Blend Mode Katmanları
İki görseli birleştirirken piksel başına karışım modu. Neon ışık, dramatik karanlık, kontrast efektleri: tek satırla sahneye katman ekle.
Blend Modes: Katman Karışım Modları GitHub ↗
Photoshop'taki Screen, Overlay, Darken gibi blend modları Ren'Py'e taşıyor. Bir arka planın üstüne ışık dokusu, renk katmanı veya atmosfer yerleştirmek için.
Tüm .rpy dosyalarını game/libs/blend-modes/ klasörüne koy. Bu mod sayesinde iki görseli üst üste getirirken karışım modunu seçebilirsin, tıpkı Photoshop katmanları gibi.
screen moduyla üst üste gelince arka plan parlar ama birleşip tek görsel olur. Gerçekçi neon, gün batımı, gece atmosferi bu şekilde yapılır.
# Kurulum: screen.rpy, overlay.rpy vb. game/libs/blend-modes/'a koy
# Kullanım: cc_[mod]("alttaki görsel", "üstteki doku"): ikisini birleştirir
# Screen: ışık dokusu ekle, arka plan parlar (neon glow, projektör)
show expression cc_screen("bg_sehir", "images/isik_doku.png") as sahne
# Overlay: kontrast güçlendir, koyu koyu açık açık olur (dramatik sahne)
show expression cc_overlay("bg_sehir", "images/renk_katman.png") as sahne
# Soft Light: hafif ışık, yumuşak atmosfer (şafak, gün batımı)
show expression cc_soft_light("bg_park", "images/sicak_doku.png") as sahne
# Bitince kaldır:
hide sahne
#ff6600 turuncu = gün batımı tonu, #001133 lacivert = gece). game/images/'e koy, adını yaz.
screenIşık bindirme: arka plan üstüne parıltı, neon glowoverlayKontrast güçlendirme: koyu alanlar daha koyu, açık alanlar daha açıksoft_lightYumuşak overlay: gün batımı, sabah atmosferilightenİki görselden daha açık olanı gösterir, doğal aydınlatmadarkenİki görselden daha koyu olanı gösterir, gece, gölgecolor_burnKaranlık alanları yoğunlaştırır, sert noir tonucolor_dodgeAçık alanları patlatır, ışık bombası, güneş efektidifferenceRenklerin farkını gösterir, ters/negatif etkiexclusionDifference'ın yumuşak hali, hayal gibi tuhaf tonvivid_lightÇok güçlü kontrast, yıldırım, enerji patlaması
Metin Efektleri
Sallanan, patlayan, gradyan, dalgalanan metin. Diyaloglara hayat ver.
Metin Dış Çizgisi & Glow: Yerleşik
Ek mod gerekmez. gui.rpy'e yapıştır, çalışır. Yazının etrafına siyah outline veya neon glow ekler.
# Siyah dış çizgi: en temel okunabilirlik çözümü
define gui.text_outlines = [(2, "#000000", 0, 0)]
define gui.name_text_outlines = [(2, "#000000", 0, 0)]
define gui.interface_text_outlines = [(1, "#000000", 0, 0)]
# Sağ-alt gölge: sinema stili
define gui.text_outlines = [(2, "#00000099", 2, 2)]
# Neon glow: birden fazla katman üst üste
define gui.text_outlines = [
(4, "#0044ff44", 0, 0), # Dışta: mavi parlama (hafif saydam)
(2, "#0088ffaa", 0, 0), # Ortada: yoğun mavi
(1, "#ffffff", 0, 0), # İçte: beyaz ince çizgi
]
kalınlıkpiksel. 1–2 = okunabilirlik, 4+ = glow efektirenkhex renk, sonuna 2 hane saydamlık eklenebilir: #00000088 = %50 opakx_offset / y_offsetçizgiyi kaydır. 0, 0 = çevreden eşit, 2, 2 = sağ-alt gölgeBirden fazla katmanlisteye virgülle ekle, her katman ayrı render edilir, glow efekti bu şekilde yapılırKinetic Text Tags: Animasyonlu Metin GitHub ↗
En popüler metin efekt kütüphanesi. Diyalog tag'leri olarak çalışır, kod gerektirmez.
d "{bt}Bu metin zıplıyor!{/bt}" # bounce: zıplayan
d "{sc=3}Titriyorum!{/sc}" # scare: titreyen, N = şiddet
d "{fi}Yavaşça hatırladım...{/fi}" # fade-in: beliren
d "{rotat=5}Dönen metin{/rotat}" # rotate: dönen, N = derece
d "{chaos}Sistem çöküyor{/chaos}" # chaos: kaotik hareket
d "{omega}Patlayan harfler!{/omega}" # omega: patlayan
d "{move=100}Kayan metin{/move}" # move: yatay kayma, N = piksel
d "{swap=Eski metin}Yeni metin{/swap}" # swap: iki metin arası geçiş
{bt}…{/bt}bounce: zıplayan harfler{sc=N}…{/sc}scare: titreyen harfler, N = şiddet (1-10){fi}…{/fi}fade-in: harfler yavaşça belirir{rotat=N}…{/rotat}rotate: dönen harfler, N = derece{chaos}…{/chaos}chaos: harfler rastgele savrulur{omega}…{/omega}omega: her harf ayrı yönde patlayarak kaybolur{move=N}…{/move}move: harfler yatayda N piksel kayar{swap=metin1}metin2{/swap}swap: iki metin arasında geçiş yapar{wave}…{/wave}wave: dalgalanan harfler (ayrı eklenti: WaveShader){glitch}…{/glitch}glitch: bozuk metin efekti (ayrı eklenti: glitch_tag.rpy){gradient=#hex1,#hex2}…{/gradient}gradient: renk geçişi (ayrı eklenti: gradient_tags.rpy)İç içe geçirme{bt}{sc=2}Hem zıplar hem titrer{/sc}{/bt}: tag'ler birleştirilebilir
Arayüz Şablonları (GUI)
Ren'Py'nin varsayılan arayüzünü tamamen değiştiren hazır temalar.
Easy Ren'Py GUI 72 ★
Derin GUI değişikliklerini kolay yapmanı sağlayan şablon. Menüler, save/load, ayarlar: her şey özelleştirilebilir.
Awesome Template 97 ★
Gelişmiş başlangıç şablonu: feather ikon GUI, göz kırpan sprite'lar, parallax arka plan.
Disco Framework Ücretsiz
Disco Elysium tarzı GUI: skill-check, iç diyalog, düşünce kabineti.
Dark Elegance Ücretsiz
Koyu temalı, zarif GUI tasarımı. Dram/gerilim oyunları için.
Telefon ve Mesajlaşma
DM sahneleri, SMS, grup sohbet, bildirimler: modern oyunlar için şart.
Messenger Emulator: Telegram Tarzı Mesajlaşma GitHub ↗
Gerçekçi sohbet arayüzü: metin, resim, ses mesajı, typing animasyonu, grup sohbet, tam DM hissi.
# Mesajlaşma sahnesine geç
call messenger_start
# Mesaj gönder (karakter tarafından)
$ send_message("Demir", "Stüdyoya gel, acil.")
$ send_message("Sen", "Ne oldu?")
$ send_message("Demir", "Kontrat hazır. İmzalaman lazım.")

Multi-Notify: Bildirim Popup'ları GitHub ↗
Birden fazla bildirim aynı anda yığılır. Sosyal medya akışı varmış hissi verir.
# Telefon bildirimi tarzı
$ renpy.notify("Demir seni takip etti")
$ renpy.notify("Yeni mesaj: 'Stüdyoda buluşalım'")
# Birden fazla bildirim üst üste görünür
$ renpy.notify("1000 dinlenme!")
$ renpy.notify("Yeni takipçi: @hana_music")
Mysterious Messenger 38 ★
Mystic Messenger tarzı tam motor: sohbet odaları, SMS, telefon aramaları, e-posta.
Speech Bubbles Ücretsiz
Klasik diyalog kutusu yerine konuşma baloncukları. Karakterlerin üstünde balonlar.
Mini Oyunlar
Visual novel'inin içine entegre edebileceğin mini oyun motorları.
Ren'Py Rhythm 139 ★
DDR tarzı ritim oyunu: otomatik beat haritası oluşturma. Müzik sahneleri için birebir.
RPG Battle Engine 104 ★
Sıra tabanlı RPG savaş sistemi.
Timed Choice Menu Ücretsiz
Zamanlı seçim: süre dolunca varsayılan seçenek aktif olur. Gerilim anları için.
Ren'Py Chess 91 ★
Stockfish AI'lı tam satranç oyunu.
Oyun Sistemleri
Başarım, ansiklopedi, galeri, müzik çalar, Discord: oyununu profesyonel yapan sistemler.
Achievements: Başarım Sistemi GitHub ↗
Xbox/Steam tarzı popup başarımlar. Gizli başarımlar, ilerleme takibi, ses efektleri. Steam ile senkronize.
# Başarımları tanımla (en üstte)
define achievement_list = [
Achievement("first_record", "İlk Kayıt", "Stüdyoda ilk şarkını kaydet"),
Achievement("met_demir", "Patron", "Demir'le tanış"),
Achievement("viral", "Viral!", "1 milyon dinlenmeyi geç"),
]
# Başarım ver (hikaye içinde)
$ achievement.grant("met_demir") # Popup belirir!
Encyclopaedia: Ansiklopedi/Kodeks GitHub ↗
Oyun içi karakter profili, terim sözlüğü, lore kitabı. Hikaye ilerledikçe sayfalar kilit açar.
# Ansiklopedi girişleri tanımla
define enc = Encyclopaedia()
define enc_demir = EncEntry(
parent=enc,
name="Demir",
text=["Plak şirketinin patronu. Soğukkanlı, hesapçı."],
locked=True # Başlangıçta kilitli
)
# Hikaye içinde kilidi aç
$ enc_demir.locked = False
GalleryPlus: CG Galeri GitHub ↗
Gelişmiş CG galeri: sayfa sistemi, döngü, kilit/aç. Yeniden oynanabilirlik için kilit açma mekanizması.
# Galeri tanımla
init python:
gp = GalleryPlus()
gp.button("cg_konser")
gp.image("cg konser_sahnesi")
gp.condition("persistent.konser_goruldu")
Universal Music Player: Müzik Odası GitHub ↗
Albüm kapağı, seek bar, sıralama, kilit/aç. Müzik temalı Neon Cross için doğrudan anlam taşır.
# Parçaları tanımla (manualtracks.rpy)
init python:
manual_music_tracks = [
MusicTrack("Gece Lambası", "audio/gece_lambasi.ogg",
artist="Neon Cross", locked=False),
MusicTrack("Sokak Felsefesi", "audio/sokak.ogg",
artist="Neon Cross", locked=True),
]
Discord Rich Presence GitHub ↗
Discord profilinde "Neon Cross oynuyor" gösterir. Arkadaşları oyunu fark eder, kendiliğinden yayılır.
# settings.rpy'de yapılandır
define discord_appid = "YOUR_APP_ID"
define discord_details = "Bölüm 1: Stüdyo"
define discord_state = "Seçim yapıyor..."

NQTR System 49 ★
Navigasyon + Görev + Zaman + Rutin: tam keşif oyunu altyapısı.
Flowchart Plug-In Ücretsiz
Zero Escape tarzı oyun içi akış şeması: hangi dalları gördüğünü göster.
Kamera ve Animasyon
ActionEditor3: Kamera Yönetmen Aracı GitHub ↗
184 ★ · Ren'Py'nin en güçlü aracı. Kamera hareketi & keyframe animasyonunu görsel editörle tasarla, kodu o üretir.
# Oyun sırasında Shift+A basarak editörü aç
# Kamera hareketini görsel olarak tasarla
# Editör sana kullanacağın kodu üretir:
show defne mutlu:
xpos 0.3 ypos 0.2 zoom 1.2
linear 1.0 xpos 0.5 zoom 1.0
Autofocus: Otomatik Karakter Odaklama GitHub ↗
Konuşmayan karakterleri otomatik karartır. Kurulum sonrası hiç elle müdahale gerekmez, her diyalogda devrede.
# Kurulum sonrası otomatik çalışır!
# Konfigürasyon (autofocus.rpy):
define autofocus.dim = 0.5 # Karartma miktarı (0-1)
define autofocus.blur = 2.0 # Bulanıklık miktarı
define autofocus.duration = 0.3 # Geçiş süresi
# Belirli bir karakteri autofocus dışında tut
show defne mutlu as defne_exempt:
autofocus_exempt = True # Bu karakter hiç kararalmaz
autofocus.dimPasif karakterlerin karartılma miktarı. 0.0 = hiç, 1.0 = tamamen siyah. varsayılan: 0.5autofocus.blurPasif karakterlerin bulanıklaştırılma miktarı (piksel). 0 = sadece karartma. varsayılan: 2.0autofocus.durationKonuşmacı değişiminde geçiş süresi (saniye). varsayılan: 0.3autofocus_exemptKarakter etiketine eklenerek o karakteri autofocus sisteminden çıkarır.Spritesheet Animation: Sprite Animasyonu GitHub ↗
Spritesheet'ten frame-by-frame animasyon. Karakterlere statik duruş yerine hayat verir.
# Spritesheet'ten animasyon tanımla
image defne_blink = SpriteSheetAnimation(
"images/defne_blink_sheet.png", # game/ klasöründen yol
columns=4, rows=1, # 4 kare yan yana, tek satır
frame_time=0.15 # her karede 0.15 saniye bekle
)
# Sonra script.rpy'de çağır:
show defne_blink
dosya yoluSpritesheet PNG'nin yolu. game/ klasöründen başlar. örnek: "images/defne_blink_sheet.png"columnsSpritesheet'teki yatay kare (sütun) sayısı. 4 kare yan yana sıraldıysa columns=4. örnek: 4rowsSpritesheet'teki dikey satır sayısı. Tek sıra animasyon = rows=1. örnek: 1frame_timeHer karenin ekranda kalma süresi (saniye). Küçültünce animasyon hızlanır. örnek: 0.15Geliştirici Araçları
Kod editörü, hata ayıklama, görselleştirme: üretim sürecini hızlandıran araçlar.
VS Code Language Ren'Py 142 ★
VS Code eklentisi: syntax highlighting, otomatik tamamlama, snippet'lar. Şart.
renpy-graphviz 175 ★
Oyunun dallanma yapısını otomatik görselleştirir. Karmaşık hikayeler için harita çıkarır.
Image Tools Araç
Karakter ifadelerini ve görsel özelliklerini editör içinde önizle/test et.
Debugger Araç
Oyun içi hata ayıklama ve değişken düzenleme.
Dialog to Audio Ücretsiz
Diyaloglardan otomatik TTS ses üretimi.
Caption Tool Ücretsiz
Erişilebilirlik için görsel ve ses alt yazıları.
Öğrenme Kaynakları
- Feniks Development. En kapsamlı Ren'Py programlama dersleri
- Ren'Py Patreon. Yaratıcının 30+ ileri seviye makalesi
- Lemma Soft Forums. Topluluk forumu, soru-cevap, kaynak paylaşımı
- awesome-renpy. 290+ kaynak listesi (her şey burada)
Ücretsiz Varlıklar (Free Assets & Themes)
Oyunun için her görseli kendin çizmek zorunda değilsin. Topluluk binlerce ücretsiz karakter, arka plan, müzik ve arayüz teması paylaşıyor, çoğu ticari projelerde de kullanılabilir.
🔍 Nerede Bakmalısın?
itch.io: Ücretsiz Ren'Py Varlıkları Ana Kaynak
Karakter çizimleri, arka planlar, müzik, arayüz temaları: hepsi etiketlenmiş, filtreleyerek bulabilirsin. 1000+ ücretsiz içerik. Filtre: free → renpy. Her gün yeni şeyler ekleniyor.
OpenGameArt.org CC Lisans
Creative Commons lisanslı müzik, ses efekti, sprite ve arka plan. VN için hazır paketler var. Filtre: "visual novel" veya "2D character".
FreeSound.org Ücretsiz
500.000+ ses efekti ve ambiyans: ayak sesleri, kapı, yağmur, şehir gürültüsü: atmosfer için vazgeçilmez. Çoğu CC0 (atıf bile gerekmez).
Lemma Soft: Resources Forum
Topluluğun yıllarca biriktirdiği kaynak arşivi: arayüz şablonları, karakter çizimleri, arka plan paketleri: ücretsiz paylaşımlarla dolu.
🎨 GUI ve Tema Paketleri
Varsayılan Ren'Py görünümü yerine hazır bir tema kullanabilirsin, tüm ekran dosyaları ve animasyonlar dahil geliyor, üzerine yaz yeter.
Easy Ren'Py GUI Ücretsiz
Feniks Dev'in en popüler paketi. Ren'Py 8 uyumlu, derin özelleştirme için hazırlanmış şablon. Kapsamlı dokümantasyonla birlikte gelir. Ticari kullanım serbest.
EasyRenPyGui (GitHub) Açık Kaynak
Shawna-p'nin GitHub'daki GUI şablonu. Temiz kod, iyi belgelenmiş. Başlangıç projesi olarak kullanmak için ideal.
itch.io GUI Koleksiyonu 50+ Tema
Dark, pastel, horror, fantasy, sci-fi: her tarza GUI teması var. Tüm ücretsiz Ren'Py GUI paketleri burada listelenmiş.
🧑🎨 Karakter Sprite Paketleri
itch.io: Ücretsiz Sprite'lar
Anime tarzı, gerçekçi, chibi: yüzlerce ücretsiz karakter paketi. Çoğu şeffaf PNG, birden fazla ifade içeriyor. Filtre: free → renpy → sprites.
OpenGameArt: VN Karakterleri
CC lisanslı VN karakterleri. Bazıları tam ifade setiyle geliyor (mutlu, üzgün, şaşkın, kızgın). Ticari projelerde kullanılabilir.
🌆 Arka Plan Paketleri
itch.io: Ücretsiz Arka Planlar
Okul, şehir, orman, korku, fantezi: yüzlerce hazır VN arka planı. HD çözünürlük, 1280×720 veya 1920×1080 formatında.
OpenGameArt: Arka Planlar
Ücretsiz, CC lisanslı environment art: iç mekan, dış mekan, fantasy dünya: geniş seçenek. Ticari kullanım için lisans kontrolü şart.
Uncle Mugen: VN Arkaplanları Klasik
Uncle Mugen'in topluluk arşivi: okul, kafe, şehir, park, orman, tropikal, ticari merkez: yıllar içinde biriktirilmiş yüzlerce VN arkaplanı. Ticari projelerde de serbest, modifikasyona açık.
🎵 Müzik ve Ses Efekti
FreeSound.org CC0
En geniş ücretsiz ses kütüphanesi. Ambiyans, UI sesleri, yağmur, rüzgar, kalp atışı: oyun atmosferi için her şey burada. Hesap açmadan indirilebilir.
OpenGameArt: VN Müzikleri
Özellikle VN için bestelenen ücretsiz müzik paketleri. Romantik, gerilim, neşeli, melankolik: farklı sahne tonları için ayrı parçalar.
itch.io: VN Müzik Paketleri
Ren'Py etiketli ücretsiz müzik paketleri. Loop-uyumlu formatlar (OGG), tam parça + kısa versiyon çoğu pakette mevcut.
🛠️ Geliştirici Araçları ve Script'ler
Achievements for Ren'Py Ücretsiz
Feniks Dev'in başarım sistemi. Popup bildirimleri, gizli başarımlar, Steam entegrasyonu, galeri ekranı dahil. Ticari kullanım serbest.
renpy-achievement (GitHub) Açık Kaynak
Shawna-p'nin başarım sistemi. Tek .rpy dosyası, minimal kurulum. Steam/GOG başarımlarıyla da çalışır.
renpy-encyclopaedia Açık Kaynak
Oyun içi ansiklopedi/lore sistemi. Karakterler, yerler, terimler için ansiklopedi ekranı. RPG ve lore-heavy VN'ler için ideal.
itch.io: Ücretsiz Araçlar
Diyalog çıkarıcı, kayıt sistemi, galeri ekranı, çeviri yardımcısı gibi hazır araçlar var. Tek sayfada hepsi.
Önerilen Eklentiler (Recommended Plugins)
Topluluğun yıllar içinde en fazla tavsiye ettiği araçlar. Hepsi ücretsiz, kopyala yapıştır kurulumu. Karta tıkla, ne yaptığını ve nasıl kurulduğunu gör.
ActionEditor3: Fareyle Karakter Konumlandırma GitHub ↗
Oyun açıkken Shift+P'ye bas, karakterleri fareyle sürükle. Konum, boyut, döndürme: kodu elle yazmadan. Bitince "Copy" düğmesine bas, kod panoya kopyalanır.
Kurulum
GitHub'dan ZIP indir → action_editor/ klasörünü game/ içine at.
Oyunu başlat → Shift+P'ye bas. Editör açılır.
Arayüz Haritası
Editör açıldığında ekranın alt kısmında timeline ve sol tarafta layer listesi belirir. Neyin ne olduğunu bilmeden dokunursan arka planı, kamerayı, yanlış katmanı oynatırsın. Önce bu haritayı oku.
Karakter Taşıma (Adım Adım)
Oyun sahneye geldiğinde Shift+P'ye bas. Editör açılır.
Sol panelde sadece karakterin adına tıkla (örn. "lila"). camera ve bg'ye dokunma — bunlara dokunursan arka plan veya tüm sahne kayar.
Karakter seçilince altında özellikler açılır: Child/Pos (konum), Zoom/Crop (boyut), Anchor/Offset (pivot noktası). En çok kullanacağın Child/Pos.
Child/Pos'u aç → xpos ve ypos değerlerini gör. Sayıya tıkla, yeni değer yaz, Enter'a bas. Karakter ekranda hareket eder. xpos=0.0 sol kenar, 0.5 orta, 1.0 sağ kenar. ypos=0.0 üst, 1.0 alt.
Pozisyondan memnunsan sağ paneldeki "clipboard" butonuna bas. Ren'Py kodu panoya kopyalanır.
VS Code'a geç → script.rpy'de ilgili sahneye Ctrl+V ile yapıştır.
xpos değerini sayı yazarak değiştir (örn. 0.3), pin'ler ayrılır, sonra sürükleyebilirsin.
Animasyon / Keyframe Ekleme
Sol panelde karakteri seç. Timeline'da mavi çubuğu başlangıç zamanına getir (0.00 s).
Karakterin xpos/ypos değerini ayarla → o zamana otomatik keyframe (◆) düşer.
Mavi çubuğu bitiş zamanına sürükle (örn. 1.00 s). Değeri değiştir → ikinci keyframe düşer.
Sağ panelden "play"'e bas — karakter iki keyframe arasında hareket eder, arka plan sabit kalır.
Beğenmediysen: "remove keys" ile seçili keyframe'leri sil, baştan dene. "close" ile kaydetmeden tamamen çıkabilirsin.
# ActionEditor çıktısı bu formatta gelir, elle yazmana gerek yok:
show kai mutlu at Position(xpos=0.3, ypos=0.1, xanchor=0.5, yanchor=0.0)
show marcus ciddi at Position(xpos=0.7, ypos=0.05, xanchor=0.5, yanchor=0.0)
Özellik Paneli Sözlüğü
xpos — yatay konum (0.0–1.0)ypos — dikey konum (0.0–1.0)zpos — derinlik (genelde 0)xaround/yaround — dönme merkeziradius/angle — dairesel hareket
zoom — genel büyüklük (1.0 = normal)xzoom — yatay ölçek (−1 = ayna)yzoom — dikey ölçekcropX/Y/W/H — kırpma alanı
xanchor/yanchor — pivot noktasıxoffset/yoffset — piksel kaydırma
rotate — 2D döndürme (derece)matrixcolor — renk efektlerialpha — saydamlık (0–1)
at right, with move, with moveinright gibi hazır geçişleri daha hızlı. Action Editor karmaşık sinematik sahneler (kamera zoom + karakter hareketi + döndürme aynı anda) için ideal.Easy Ren'Py GUI: Hazır Profesyonel Arayüz itch.io ↗
Varsayılan Ren'Py arayüzünü tamamen değiştirir. Kaydet ekranı, ayarlar, ana menü, geçmiş paneli: hepsi yeniden tasarlanmış halde geliyor. Renk ve font değiştirmek için tek bir dosyaya bakman yeterli.
Kurulum
itch.io'dan ZIP'i indir ve aç.
ZIP içindeki game/ klasörünün içeriğini kendi projenin game/ klasörüne kopyala. Dikkat: script.rpy'ni kopyalama, sadece gui/, gui.rpy, screens.rpy dosyalarını al.
Oyunu başlat. Yeni arayüz hazır.
Nasıl Kullanılır?
gui.rpy dosyasını VS Code'da aç. Tüm renkler, fontlar, boyutlar bu tek dosyada.
gui.accent_color değerini değiştir → ana menü, butonlar, başlık rengi hep birlikte güncellenir.
Font değiştirmek için .ttf dosyasını game/fonts/'a at, gui.text_font'a yolunu yaz.
Buton/arka plan görseli değiştirmek için game/gui/ klasöründeki PNG dosyalarını kendi tasarımınla değiştir. Aynı isim + aynı boyut yeterli.
# gui.rpy: bunları değiştir, tüm arayüz güncellenir:
define gui.accent_color = "#7df9ff" # Ana renk (buton, başlık, vurgular)
define gui.hover_color = "#b4fcff" # Üzerine gelince renk
define gui.text_font = "fonts/Benim.ttf" # Oyun fontu
define gui.text_size = 28 # Normal metin boyutu
define gui.title_text_size = 60 # Ana menü başlık boyutu
game/gui/ klasöründeki dosyalar: main_menu.png (arka plan), textbox.png (diyalog kutusu), choice_idle_background.png (seçenek butonu). Aynı isimle kendi PNG'lerini koy.VS Code + Ren'Py Eklentisi: Kod Editörü GitHub ↗
Ren'Py kodunu VS Code'da yazarsan renklendirme, otomatik tamamlama ve hata işaretleme geliyor. Launcher'ın kendi editörüne kıyasla çok daha rahat yazarsın.
Kurulum
code.visualstudio.com'dan VS Code'u indir ve kur.
VS Code'u aç → Sol tarafta Extensions (Ctrl+Shift+X) → "renpy" ara → Ren'Py Language kur.
Ren'Py Launcher'ında Preferences → Text Editor → Visual Studio Code seç.
Nasıl Kullanılır?
Launcher'da projenin üzerindeyken "Edit File" veya "script.rpy"'ye tıkla → dosya VS Code'da açılır.
Ren'Py komutları (show, scene, menu, label) otomatik renklendirilir. Yanlış yazarsan kırmızı altı çizili uyarı gelir.
Yazmaya başla → Ctrl+Space'e bas → komut listesi açılır, Enter'la seç. Her şeyi ezbere bilmene gerek yok.
Ctrl+P → dosya adı yaz, dosyalar arası hızlıca atla. Ctrl+Shift+F → tüm dosyalarda kelime arama.
2
3
4
5
6
7
8
renpy-graphviz: Hikaye Haritası GitHub ↗
Oyunundaki tüm label'ları ve jump bağlantılarını otomatik çizerek bir akış şeması oluşturur. Hangi sahnenin nereye bağlandığını görmek için ideal, özellikle dal sayısı artınca.
Kurulum
Terminalde: pip install renpy-graphviz
Proje klasöründe çalıştır: renpy-graphviz game/
Nasıl Kullanılır?
Terminal'i aç (VS Code'da Ctrl+`), projenin kök klasörüne git.
renpy-graphviz game/ --output hikaye.png yaz, Enter'a bas.
Oluşan PNG'yi aç. Her kutu = bir label, her ok = bir jump veya call. Farklı renkler farklı .rpy dosyalarını gösterir.
Ok çıkmayan kutular = çıkmaz sokak. Oyuncunun takılacağı yerler, bunları düzelt.
# Terminal: proje kök klasöründe çalıştır
renpy-graphviz game/ --output hikaye-haritasi.png
# SVG formatında (yakınlaştırılabilir, büyük projeler için):
renpy-graphviz game/ --output hikaye-haritasi.svg --format svg
Messenger Emulator: Telefon Mesajlaşma Arayüzü GitHub ↗
Oyun içinde Telegram benzeri bir mesajlaşma ekranı açar. Modern VN'lerin vazgeçilmezi: karakterin seninle mesajlaştığı sahneler için.
Kurulum
GitHub'dan ZIP indir → messenger/ klasörünü game/ içine at.
Konfigürasyon dosyasında kişileri tanımla (isim, profil resmi, renk).
Nasıl Kullanılır?
Önce kişileri ayarla: config dosyasında her karakter için isim, profil fotoğrafı ve balon rengi belirle.
Sahnede telefon ekranını açmak istediğin yere call screen messenger_screen yaz.
Mesajları sırayla ekle: side="left" = karşı tarafın mesajı, side="right" = oyuncunun mesajı.
"Yazıyor..." efekti, okundu tiki ve fotoğraf gönderme gibi özellikler de var, GitHub sayfasındaki dokümantasyona bak.
# script.rpy: telefon sahnesinde kullan
label mesaj_sahnesi:
call screen messenger_screen:
message "kai" "Neredesin?" side="left"
message "player" "Yoldayım." side="right"
message "kai" "Çabuk gel." side="left"
Achievements: Başarım Sistemi GitHub ↗
Oyun içinde başarım kazanılınca ekranda popup çıkar. Gizli başarımlar, ilerleme takibi ve Steam entegrasyonu var. Oyuncuyu tekrar oynamaya teşvik eder.
Kurulum
GitHub'dan achievements.rpy dosyasını indir → game/ klasörüne at. Bitti.
Nasıl Kullanılır?
Başarımları ÜST BÖLGE'de (label'dan önce) define ile tanımla. İsim + açıklama yeterli.
Kazanılacağı yerde $ başarım.grant() yaz. Ekranın köşesinde otomatik popup çıkar.
Gizli başarım istiyorsan hidden=True ekle, oyuncu kazanmadan önce göremez.
Tüm başarımları listeleyen ekran için menüye buton ekle: call screen achievements_screen.
# ÜST BÖLGE: başarımları tanımla
define a_ilk_secim = Achievement(
name="İlk Adım",
description="İlk seçimini yaptın."
)
define a_gizli_son = Achievement(
name="Karanlık Yol",
description="Gizli sonu buldun.",
hidden=True
)
# ALT BÖLGE: oyuncu seçim yapınca kazandır
label ilk_karar:
menu:
"Kabul et":
$ a_ilk_secim.grant() # 🏆 popup çıkar!
jump devam
Multi-Notify: Ekran Bildirimleri GitHub ↗
Oyun sırasında ekranın köşesinde küçük bildirim baloncuğu çıkarır. Aynı anda birden fazla bildirim çalışabilir. Başarım veya ipucu göstermek için ideal.
Kurulum
GitHub'dan multi_notify.rpy dosyasını indir → game/ klasörüne at. Bitti, tek dosya.
Nasıl Kullanılır?
Bildirimi göstermek istediğin yere $ notify("mesaj") yaz. Ekranın üst köşesinde belirip birkaç saniye sonra kaybolur.
Aynı anda birden fazla bildirim gösterebilirsin, üst üste yığılır, birbirini ezmez.
Eşya bulma, bölüm geçişi, ipucu verme, sistem mesajı gibi durumlarda kullan.
# Tek bildirim, köşede belirip kaybolur
$ notify("Yeni mesaj geldi.")
# Aynı anda birden fazla bildirim
$ notify("🏆 Başarım: İlk Adım")
$ notify("📍 Bölüm 2: Park")
# Eşya bulma sahnesinde:
label esya_bul:
$ notify("🔑 Anahtar bulundu!")
"Yerde bir anahtar var. Cebime attım."
renpy.notify() fonksiyonu aynı anda sadece 1 bildirim gösterir ve üst üste biner. Bu eklenti birden fazla bildirimi düzgünce yığar.🏁 İlk Projeyi Nasıl Bitirirsin?
Ren'Py topluluğunda en çok duyulan şikayet şu: "Harika bir fikrim vardı, 3 ay uğraştım, yarıda bıraktım." Sebebi teknik değil, işi fazla büyütmek.
MVP Kuralı: Minimal Çalışan Proje
İlk oyunun için bu sınırları kendine koy:
✓ Olması Gerekenler
5–10 sahne · 2–3 karakter · 1–2 dal (farklı son) · Temel müzik · Launcher'dan çalışıyor
✗ İkinci Oyuna Bırak
Özel GUI · Achievement sistemi · Animasyonlu spritelar · 30+ sahne · Türkçe/İngilizce lokalizasyon
Scope Kontrol Listesi
Önce hikayeyi yaz. Tüm sahne metinlerini düz .txt dosyasında tamamla. Ren'Py koduna geçmeden önce hikaye bitmeli.
Geçici görseller kullan. Renk blokları veya ücretsiz hazır çizimlerle başla, sanat sonra gelir. Görsel bitmeden kodu durdurma.
Her hafta test et. Launcher'dan Play bas, baştan oyna. "Sonra test ederim" dersen hata birikir, motivasyon düşer.
1.0'ı itch.io'ya koy. Mükemmel değil, bitmiş olsun. Geri bildirim alınca 1.1 yapar sürümü geliştirirsin.
☕ Örnek Oyun: Kahve Molası
Rehberde anlatılan her şeyi kullanan minik bir oyunu birlikte yapıyoruz. Sonunda elinde çalışan, iki farklı sona giden bir oyun olacak.
Hiç Ren'Py açmamış birine göre yazıldı: hangi dosyayı nereye koyduğumuzu, neden o satırı yazdığımızı, hangi görseli hangi klasöre attığımızı tek tek söyleyeceğim.
Hikaye özeti: Sen kafede kitap okuyorsun. Lila adında biri yanına gelip oturuyor. Onunla konuşur musun, yoksa kitabını mı okumaya devam edersin? Akşam olduğunda Lila kalkıyor. Gece sokakta yalnız mısın, yoksa Lila ile birlikte mi yürüyorsun? Verdiğin her seçim ruh_hali değişkenini değiştiriyor; oyun sonu o değişkene göre belirleniyor.
1. Adım: Yeni Proje Aç
Ren'Py launcher'ı aç (İlk Projen bölümünde anlatıldı). Sol tarafta + Create New Project'e tıkla. Sırasıyla:
Project name: kahve-molasi yaz. (Türkçe karakter ve boşluk koyma, Ren'Py launcher dosya adında sorun çıkarabilir.)
Resolution: 1920×1080 seç. Modern monitör standardı, oyun ekranını dolduracak.
Color scheme: Beğendiğin bir renk seç, bu sadece ana menünün rengi, sonra değiştireceğiz.
Launcher proje oluşturduktan sonra sol listede kahve-molasi görünecek. Üstüne tıkla, sağ taraftan game butonuna bas, proje klasörü açılır.
Açılan klasörde game/ içinde şu dosyaları göreceksin: script.rpy (asıl hikaye), options.rpy (oyun ayarları), screens.rpy (arayüz), gui.rpy (görünüm). Yapacağımız iş %90 oranında script.rpy'de geçecek.
2. Adım: Klasörleri Kontrol Et
game/ klasörünü aç. Ren'Py proje oluşturduğunda bu klasörleri ve dosyaları zaten yaratmış olur:
game/
├── images/ ← arka plan ve karakter çizimleri buraya
├── audio/ ← müzik ve ses dosyaları buraya
├── script.rpy
├── options.rpy
├── screens.rpy
└── gui.rpy
images/ ve audio/ hazır durumda. Dosya Yapısı bölümünde de anlatıldığı gibi, Ren'Py images/ klasöründeki görselleri otomatik tanır, dosya adından bir image tag üretir. Yani images/bg kafe gunduz.jpg dosyası varsa, scene bg kafe gunduz yazınca onu kullanır. Dosya adındaki boşluklar tag'e dönüşür.
3. Adım: Asset'leri İndir ve Yerleştir
Bu oyun için gereken tüm görseller ve müzik tek ZIP'te. İndir, game/ klasörüne aç, kodlamaya başla.
ZIP'i açtığında içinden images/ ve audio/ klasörleri çıkacak. Bunları game/ klasörünün içine kopyala. Sonuç şöyle olmalı:
game/
├── images/
│ ├── bg kafe gunduz.jpg
│ ├── bg kafe aksam.jpg
│ ├── bg sokak gece.jpg
│ └── lila normal.png
├── audio/
│ └── kafe.ogg
├── script.rpy
└── ...
bg kafe gunduz.jpg
Gündüz vakti, sıcak ışıklı bir kafe içi.
bg kafe aksam.jpg
Aynı kafenin akşam hali: turuncu tonlar, loş ışık.
bg sokak gece.jpg
Gece sokağı: sokak lambaları, ıslak asfalt.
lila normal.png
Saydam arka planlı karakter sprite'ı.
kafe.ogg
Sakin kafe müziği, döngüde çalar.
Dosya isimleri tam olarak yukarıdaki gibi olsun: küçük harf, boşluklu. Ren'Py boşlukları ayraç olarak kullanır.
4. Adım: script.rpy'yi Tamamen Sil ve Sıfırdan Yaz
Launcher'da script.rpy'ye tıkla, varsayılan editör (Atom/VS Code) açılır. İçindeki her şeyi sil. Korkma, yedeği zaten launcher'dan tek tıkla geri alınır. Aşağıdaki kodu parça parça yazacağız.
5. Adım: Karakterleri Tanımla
İlk olarak konuşacak kişileri tanımlıyoruz. Karakterler bölümünde detayı var.
# --- Karakterler ---
define ben = Character("Sen", color="#7df9ff")
define l = Character("Lila", color="#ff9de2")
define n = Character(None, what_color="#9aa3ad", what_italic=True)
Neden böyle? ben ana karakter (oyuncu): neon mavi rengi seçtim çünkü kafedeki yapay ışıkla uyuyor. l Lila: pembe, soft bir karakter olduğunu hissettiriyor. n ise narrator: ismi yok (None), italik yazılır, gri tonda, ortam anlatımı için.
define kullanıyoruz. Değişkenler bölümünde detay var.6. Adım: Değişkeni Oluştur
Hikayenin sonunu belirleyecek tek bir sayı kullanacağız: ruh_hali. Lila ile yakınlaşırsan artar, yalnız kalırsan düşer.
# --- Değişkenler ---
default ruh_hali = 0
default, neden define değil?define = dövme gibi, asla değişmez (karakter tanımı).default = saç rengi gibi, başlangıçta bir değer var ama sonra değişebilir.ruh_hali oyun boyunca artıp azalacak → default kullanıyoruz. define yazsaydık, oyuncu kayıt yükleyince ruh_hali hep 0'a dönerdi, seçimler kaybolurdu.Değişkenler bölümündeki "define vs default" tablosu tam bunu anlatıyor.
# --- Karakterler ---
define ben = Character("Sen", color="#7df9ff")
define l = Character("Lila", color="#ff9de2")
define n = Character(None, what_color="#9aa3ad", what_italic=True)
# --- Değişkenler ---
default ruh_hali = 0
# (label start buraya gelecek, bir sonraki adımda)
7. Adım: Açılış Sahnesi
Şimdi oyunun ilk anını yaz. label start: Ren'Py'nin nereden başlayacağını söylediği özel etiket, her oyunda olmak zorunda.
label start:'ın altına yaz (her satır 4 boşluk girintili)label start:
scene bg kafe gunduz
with fade
play music "audio/kafe.ogg" fadein 2.0
n "Pencere kenarındaki masada oturuyorsun. Önünde yarım kahve, kucağında kitap."
n "Kafenin uğultusu kulak yormuyor, alıştığın bir ses."
ben "Bugünlük başka kimseyi görmesem iyi olur."
Satır satır ne yaptık:
scene bg kafe gunduz:bg kafe gunduz.jpgdosyasını arka plan yapar. Ekrandaki her şeyi siler, sadece bunu gösterir.with fade: siyahtan açılır. Geçişler bölümündekifadeefekti.play music "audio/kafe.ogg" fadein 2.0: Müzik 2 saniyede yumuşakça açılır. Müzik bölümü tam burayı anlatıyor.n "...": Narrator konuşuyor, italik gri.ben "...": Sen konuşuyorsun, neon mavi.
8. Adım: Lila Sahneye Girsin
Şimdi karakter sprite'ını ekrana getiriyoruz. Görseller ve Pozisyonlar bölümlerinin uygulaması:
show lila normal at center
with dissolve
l "Buraya oturmamın bir sakıncası var mı?"
n "Başını kaldırıyorsun. Tanımıyorsun ama gözleri tanıdık."
Dikkat edilen noktalar:
show lila normal:lila normal.pngdosyasını sahneye ekler. scene'in aksine arka planı silmez, üstüne ekler.at center: Ortaya konumlanır.at leftveyaat rightda var.with dissolve: Sprite yumuşakça beliriyor.fadeekranı karartır,dissolvesadece değişen şeyi karşıtırır: karakter girişi için doğru olan budur.
at center, at left, at right yeterli gelmiyorsa iki yolun var:
Yol 1 — Kodla (hızlı): Position() ile tam koordinat ver:
show lila normal at Position(xpos=0.4, ypos=0.05, xanchor=0.5, yanchor=0.0)
with dissolve
Yol 2 — ActionEditor3 ile görsel olarak: Oyunda Shift+P'ye bas, sol panelden sadece karakter adına tıkla (camera/bg'ye dokunma!), xpos/ypos değerlerini değiştir, sonra "clipboard" butonuyla kodu al. Detaylı kullanım: Eklentiler bölümü.
9. Adım: İlk Seçim Menüsü
Burada oyuncu ilk kararı verecek. Menüler bölümündeki yapı:
menu:
"Otur, hoş geldin de.":
$ ruh_hali += 1
jump lila_konus
"Kitabıma dön, görmezden gel.":
$ ruh_hali -= 1
jump kitap_oku
$ "bu satır Python kodu" anlamına gelir. $ ruh_hali += 1 = değişkeni 1 artır.
10. Adım: İki Dal: Konuşma vs Kitap
label lila_konus:
l "Ben Lila."
ben "Ben de...{w=0.5} pek konuşkan biri değilim aslında."
l "{sc=2}Sorun değil{/sc}. Sessizce de oturulabilir burada."
n "Gülümsüyor. Kitabını çantadan çıkarıp masaya koyuyor."
jump aksam_oluyor
label kitap_oku:
n "Başını kitabına gömüyorsun. Lila bir süre bekliyor, sonra çantasından kendi kitabını çıkarıyor."
n "İkiniz de aynı masada, ama farklı dünyalardasınız."
jump aksam_oluyor
İki dal, bir birleşme: Hem
lila_konus hem kitap_oku aynı yere (jump aksam_oluyor) bağlanıyor. Hikaye çatallanıp tekrar birleşiyor.
11. Adım: Akşamı Getir (Gündüz → Akşam Geçişi)
label aksam_oluyor:
n "Pencerenin dışındaki gökyüzü turuncuya dönüyor."
scene bg kafe aksam
show lila normal at center
with Dissolve(4.0)
l "Geç oldu. Ben kalkayım."
Buradaki sihir: with Dissolve(4.0) (büyük D ile ve parantezli). 4 saniyelik özel bir geçiş. Gündüz arka planı, yavaşça akşam arka planına dönüşüyor. Karakter sahneye yeniden konduğu için aynı yerde kalıyor ama ortam değişti. Geçişler bölümünün ikinci yarısında bu detayı verdim.
12. Adım: İkinci Seçim Menüsü
menu:
"'Birlikte yürüyelim mi?' diye sor.":
$ ruh_hali += 1
jump birlikte_yuru
"'Kendine iyi bak' de, otur.":
$ ruh_hali -= 1
jump yalniz_kal
13. Adım: Sokağa Çıkış ve İki Son
label birlikte_yuru:
hide lila
scene bg sokak gece
with fade
show lila normal at center
with dissolve
n "Soğuk ama temiz bir hava. Yan yana yürüyorsunuz."
l "Bu kafeye sık geliyor musun?"
ben "Artık daha sık geleceğim galiba."
jump son
label yalniz_kal:
n "Lila kapıdan çıkıyor. Pencereden onu izliyorsun."
n "Yarısı kalmış kahve, yarısı okunmuş kitap, ve bir tanıdık daha az."
scene bg sokak gece
with fade
n "Eve dönüş yolundasın. {sc=3}Yalnız.{/sc}"
jump son
14. Adım: Koşullu Final
label son:
stop music fadeout 3.0
if ruh_hali >= 2:
n "Bazı tanışmalar planlanmaz; sadece olur."
n "İyi bir gündü."
elif ruh_hali == 0:
n "Belki başka bir gün, başka bir kafede."
else:
n "Bir kapı kapandı. Belki açıktı, sen mi kapadın?"
pause 2.0
n ". Son. "
return
Final kısmı 3 farklı son veriyor:
stop music fadeout 3.0: Müzik 3 saniyede sönüyor.if / elif / else: Python koşulu (Değişkenler bölümündeki örneklerin uygulaması). Her iki seçimi de "Lila yönünde" yaptıysaruh_hali2 olur, mutlu son. Eşitse nötr son. Negatifse hüzünlü son.pause 2.0: 2 saniye boşluk, oyuncu nefes alsın.return: Ana menüye döner. Oyunu Bitirme bölümünde anlatıldı.
15. Adım: Metin Etiketleri ile Diyalogları Canlandır
Şimdi sade diyalogları daha dramatik yapalım. Metin Etiketleri bölümündeki {w}, {cps}, {color}, {nw}/{fast} ve {b} etiketlerini script'e serpiştiriyoruz:
# Açılış sahnesinde (label start):
n "Pencere kenarındaki masada oturuyorsun.{w=0.8} Önünde yarım kahve, kucağında kitap."
# Lila girişinde:
l "{cps=15}Buraya oturmamın...{/cps}{cps=*2} bir sakıncası var mı?{/cps}"
# Birlikte yürürken (label birlikte_yuru):
ben "Artık daha sık geleceğim {color=#ff9de2}galiba{/color}."
# Yalnız kalırken (label yalniz_kal): metin birleştirme:
n "Eve dönüş yolundasın.{nw}"
n "Eve dönüş yolundasın.{fast} {b}Yalnız.{/b}"
{cps=15} → Saniyede 15 harf, yavaş yavaş yazılır, tereddüt hissi.
{color=#ff9de2}...{/color} → Lila'nın rengini "galiba" kelimesine koyarak duygusal vurgu.
{nw} + {fast} → İlk satır anında geçer, ikinci satırda "Yalnız." yeni metin olarak eklenir, kesintisiz akış.
16. Adım: Ses Efekti ve Gelişmiş Müzik
Müzik bölümünde öğrendiğimiz fadein, if_changed, volume ve ses efektlerini kullanalım:
# Açılış sahnesinde (label start): müzik yavaşça açılsın:
play music "audio/kafe.ogg" fadein 2.0 volume 0.6
# Lila otururken: bardak sesi:
play sound "audio/bardak.ogg"
l "Buraya oturmamın bir sakıncası var mı?"
# Akşam sahnesinde: aynı müzik kesintisiz devam etsin:
play music "audio/kafe.ogg" if_changed
# Sokak sahnesinde: farklı müzik geçişi:
play music "audio/gece.ogg" fadeout 1.5 fadein 2.0
play sound → Tek seferlik ses efekti, müziği etkilemez.
if_changed → Aynı parça çalıyorsa baştan başlatma, kesintisiz devam et.
fadeout + fadein → Eski müzik solar, yeni yavaşça girer.
17. Adım: gui.rpy ile Görünümü Özelleştir
Özelleştirme ve Metin Efektleri bölümlerinin uygulaması. gui.rpy dosyasını aç ve şu satırları bul, değiştir:
Renk Teması
# Renk teması
define gui.accent_color = '#7df9ff' # Neon mavi vurgu
define gui.text_color = '#ffffff' # Beyaz diyalog metni
define gui.hover_color = '#ffffff' # Buton hover
# Metin dış çizgisi: arka plan ne olursa olsun yazı okunur
define gui.text_outlines = [(2, "#000000", 0, 0)]
define gui.name_text_outlines = [(2, "#000000", 0, 0)]
# Pencere başlığı
define config.name = _("Kahve Molası")
define config.version = "1.0"
define gui.show_name = True
Font Değiştir
Varsayılan font sıkıcı görünür. Ücretsiz bir font indir (Google Fonts'tan .ttf dosyası) ve game/ klasörüne at. Sonra gui.rpy'de şu satırı bul ve değiştir:
# Font dosyasını game/ klasörüne at, sonra burada adını yaz:
define gui.text_font = "NotoSansTR-Regular.ttf"
define gui.name_text_font = "NotoSansTR-Bold.ttf"
Diyalog Kutusu ve İsim Kutusu
Varsayılan diyalog kutusu düz siyah bir dikdörtgen. Kendi görselini koymak oyunun havasını tamamen değiştirir.
game/gui/
├── textbox.png ← diyalog kutusu (1920×335 px)
├── namebox.png ← karakter isim kutusu (413×57 px)
└── overlay/
├── main_menu.png ← ana menü arka planı (1920×1080)
└── game_menu.png ← kayıt/yükleme menüsü arka planı
textbox.png: 1920×335 piksel, yarı saydam PNG. Alt kısımda oturan diyalog kutusu. Canva, Photoshop veya Photopea (ücretsiz, tarayıcıda çalışır) ile yap. Yarı saydam siyah/koyu mavi dikdörtgen + yumuşak kenarlar yeterli.
namebox.png: 413×57 piksel, saydam PNG. Karakter isminin arkasındaki küçük kutu.
Yeni görseli aynı isimle game/gui/ klasörüne at, eskisinin üstüne yaz. Ren'Py yeniden başlatınca otomatik kullanır.
gui.rpy'den de ayarlayabilirsin:
# Diyalog kutusu arka plan rengi (RGBA: son değer saydamlık)
define gui.textbox_height = 278
define gui.text_xpos = 268
define gui.text_ypos = 50
Menü Seçenek Butonları
Oyuncu seçim yaparken ("Otur, hoş geldin de" / "Kitabıma dön") butonların görünümü önemli. gui.rpy'de:
# Seçim butonları boyutu
define gui.choice_button_width = 1185
define gui.choice_button_height = None # İçeriğe göre otomatik
define gui.choice_button_text_font = "NotoSansTR-Regular.ttf"
define gui.choice_button_text_size = 33
define gui.choice_button_text_idle_color = '#cccccc'
define gui.choice_button_text_hover_color = '#ffffff'
Daha ileri gitmek istersen gui/button/ klasöründeki görselleri de değiştirebilirsin:
game/gui/button/
├── choice_idle_background.png ← normal hali
└── choice_hover_background.png ← fare üstündeyken
Hazır GUI Template (opsiyonel)
Elle her şeyi ayarlamak yerine, topluluk tarafından yapılmış hazır GUI şablonları var. İndir, game/ klasörüne at, anında profesyonel görünüm:
Easy Ren'Py GUI
Feniks'in projesi. Varsayılan gui.rpy'yi sadeleştirip kolay özelleştirilebilir hale getiriyor. Ren'Py 8.2+ destekli. Ücretsiz, ticari kullanıma açık.
AIO GUI Template
All-In-One şablon. Özel butonlar, animasyonlu geçişler, modern görünüm. MIT lisanslı.
Magical Template
Animasyonlu menüler, parıltı efektleri, tam kodlanmış. Fantasy/büyü temalı projeler için ideal.
gui.rpy, screens.rpy ve gui/ klasörünü kendi projeninkiyle değiştir. Ama script.rpy'yi değiştirme, o senin hikayen.18. Adım: Autofocus: Konuşmayana Otomatik Karartma
Kamera & Animasyon bölümündeki Autofocus eklentisi. İki karakter sahnedeyken, konuşmayan otomatik kararır, sıfır ek kod. Kurulum:
# autofocus.rpy dosyasını GitHub'dan indir,
# game/ klasörüne at. Sonra script.rpy'nin üstüne ekle:
define autofocus.dim = 0.5 # Konuşmayan %50 karartma
define autofocus.blur = 1.5 # Hafif bulanıklık
define autofocus.duration = 0.3 # Geçiş süresi
Bu kadar. Artık sahnede birden fazla karakter varken, konuşan karaktere otomatik odaklanılır. Kahve Molası'nda tek karakter var ama ikinci bir karakter (mesela barista) eklersen farkı hemen görürsün.
19. Adım: Başarım (Achievement) Sistemi Ekle
Eklentiler bölümündeki Achievements eklentisini kur (achievements.rpy dosyasını game/ klasörüne at). Sonra başarımları tanımla:
define a_ilk_sohbet = Achievement(
name="İlk Sohbet",
description="Lila ile konuştun."
)
define a_gece_yuruyusu = Achievement(
name="Gece Yürüyüşü",
description="Lila ile birlikte yürüdün."
)
# label lila_konus'un başına ekle:
$ a_ilk_sohbet.grant()
# label birlikte_yuru'nun başına ekle:
$ a_gece_yuruyusu.grant()
Oyuncu başarımı açınca ekranın köşesinde popup çıkar. Detaylı kurulum ve gizli başarımlar için Eklentiler bölümüne bak.
20. Adım: Bildirim Popup'ları
Ren'Py'nin yerleşik bildirim fonksiyonu: ekranın köşesinde küçük bir mesaj belirir, birkaç saniye sonra kaybolur. Ek dosya gerektirmez:
# Lila girişinden sonra:
$ renpy.notify("Yeni karakter tanındı: Lila")
# Birlikte yürürken:
$ renpy.notify("Başarım: Gece Yürüyüşü 🌙")
# Final'de, mutlu sonda:
$ renpy.notify("Tebrikler! İyi son.")
renpy.notify() yerleşik fonksiyondur, ek dosya gerekmez. Aynı anda birden fazla bildirim göstermek istersen Eklentiler bölümündeki Multi-Notify eklentisini kur.21. Adım: Karakter Giriş Animasyonu (offscreenleft)
Pozisyonlar bölümündeki offscreenleft ile karakter ekran dışından yürüyerek girsin:
# Lila sahneye girişini değiştir (label start):
show lila normal at offscreenleft
with None # Sessizce ekran dışına koy
show lila normal at center
with move # Soldan ortaya kayarak gelir
play sound "audio/bardak.ogg"
move geçişiyle ortaya kayar. Geçişler bölümündeki with None trick'inin uygulaması.
22. Adım: Blend Mode ile Atmosfer Katmanı
Blend Mode bölümündeki teknikle kafe sahnesine sıcak ışık efekti ekle. Bunun için images/ klasörüne bir ışık doku görseli at:
# script.rpy: define bloğuna ekle:
image kafe_isik = im.MatrixColor("images/isik_doku.png",
im.matrix.opacity(0.3))
# label start'ta sahne kurduktan sonra:
scene bg kafe gunduz
with fade
show kafe_isik # Sıcak ışık katmanı arka planın üstüne eklenir
Turuncu-sarı bir PNG (lens flare, bokeh veya gradient) koyarsan kafenin sıcak ışığı hissedilir. im.matrix.opacity(0.3) %30 saydamlık verir, çok baskın olmasın.
23. Adım: Test Et
Launcher'a dön. kahve-molasi seçili haldeyken sağ tarafta yeşil Launch Project (veya Play) butonuna bas. Oyun açılacak.
Hata varsa: Ekranda kırmızı bir uyarı çıkarsa panik yapma. Ren'Py satır numarasıyla birlikte sorunu söyler. Genellikle girinti (indentation) hatası olur. label altındaki satırlar 4 boşluk içeriden başlamalı.
Görsel görünmezse: Dosya adı tam eşleşiyor mu? images/bg kafe gunduz.jpg dosyası mı, yoksa BG Kafe Gunduz.JPG mi? Ren'Py küçük/büyük harfe duyarlı olabilir.
Müzik çalmıyorsa: audio/kafe.ogg mevcut mu? OGG formatında mı?
Tüm dalları test et: hem konuş, hem görmezden gel; hem birlikte yürü, hem yalnız kal. Üç farklı son görmelisin.
24. Adım: Dağıtım Build'i
Bittiyse paketleyelim. Launcher'da kahve-molasi seçili, sağ menüde Build Distributions'a tıkla. Açılan ekranda:
PC: Windows + Linux birlikte tek paket: kutuyu işaretli bırak.
Mac: Mac kullanıcıları için ayrı paket, istersen işaretle.
Web: İlk projende karmaşıklaştırma, sonra ekleyebilirsin.
Sağ altta Build'a bas. Birkaç dakika bekle. Bittiğinde kahve-molasi-1.0-pc.zip dosyası proje klasöründe oluşur.
Bu zip'i itch.io'ya yükle ve dünyaya aç. Bittin!
Tamamlanmış script.rpy: Kopyala-Yapıştır
Aşağıdaki blok, yukarıda parça parça yazdığımız her şeyin tek dosyaya birleştirilmiş halidir. Bonus bölümlerindeki özellikler dahil: metin etiketleri, ses efekti, bildirimler, offscreen giriş. script.rpy'yi aç, içini sil, bunu yapıştır:
# ═══════════════════════════════════════════
# Kahve Molası: örnek oyun (bonus dahil)
# ═══════════════════════════════════════════
# --- Karakterler ---
define ben = Character("Sen", color="#7df9ff")
define l = Character("Lila", color="#ff9de2")
define n = Character(None, what_color="#9aa3ad", what_italic=True)
# --- Autofocus ayarı (autofocus.rpy kuruluysa) ---
define autofocus.dim = 0.5
define autofocus.blur = 1.5
define autofocus.duration = 0.3
# --- Özel geçiş tanımları ---
define yavas_gecis = Dissolve(4.0)
define dramatik_fade = Fade(0.5, 1.0, 0.5)
# --- Değişkenler ---
default ruh_hali = 0
# --- Hikaye başlangıcı ---
label start:
scene bg kafe gunduz
with fade
play music "audio/kafe.ogg" fadein 2.0 volume 0.6
n "Pencere kenarındaki masada oturuyorsun.{w=0.8} Önünde yarım kahve, kucağında kitap."
n "Kafenin uğultusu kulak yormuyor, alıştığın bir ses."
ben "Bugünlük başka kimseyi görmesem iyi olur."
# Lila ekran dışından yürüyerek girer
show lila normal at offscreenleft
with None
show lila normal at center
with move
play sound "audio/bardak.ogg"
l "{cps=15}Buraya oturmamın...{/cps}{cps=*2} bir sakıncası var mı?{/cps}"
n "Başını kaldırıyorsun. Tanımıyorsun ama gözleri tanıdık."
$ renpy.notify("Yeni karakter: Lila")
menu:
"Otur, hoş geldin de.":
$ ruh_hali += 1
jump lila_konus
"Kitabıma dön, görmezden gel.":
$ ruh_hali -= 1
jump kitap_oku
label lila_konus:
l "Ben Lila."
ben "Ben de...{w=0.5} pek konuşkan biri değilim aslında."
l "{sc=2}Sorun değil{/sc}. Sessizce de oturulabilir burada."
n "{fi}Gülümsüyor. Kitabını çantadan çıkarıp masaya koyuyor.{/fi}"
jump aksam_oluyor
label kitap_oku:
n "Başını kitabına gömüyorsun.{w=1.0} Lila bir süre bekliyor, sonra çantasından kendi kitabını çıkarıyor."
n "{i}İkiniz de aynı masada, ama farklı dünyalardasınız.{/i}"
jump aksam_oluyor
label aksam_oluyor:
n "Pencerenin dışındaki gökyüzü turuncuya dönüyor."
play music "audio/kafe.ogg" if_changed
scene bg kafe aksam
show lila normal at center
with yavas_gecis
l "Geç oldu. Ben kalkayım."
menu:
"'Birlikte yürüyelim mi?' diye sor.":
$ ruh_hali += 1
jump birlikte_yuru
"'Kendine iyi bak' de, otur.":
$ ruh_hali -= 1
jump yalniz_kal
label birlikte_yuru:
hide lila
scene bg sokak gece
with fade
play music "audio/gece.ogg" fadeout 1.5 fadein 2.0
show lila normal at center
with dissolve
$ renpy.notify("Gece Yürüyüşü 🌙")
n "Soğuk ama temiz bir hava. Yan yana yürüyorsunuz."
l "Bu kafeye sık geliyor musun?"
ben "Artık daha sık geleceğim {color=#ff9de2}galiba{/color}."
jump son
label yalniz_kal:
n "Lila kapıdan çıkıyor. Pencereden onu izliyorsun."
n "Yarısı kalmış kahve, yarısı okunmuş kitap, ve bir tanıdık daha az."
scene bg sokak gece
with dramatik_fade
play music "audio/gece.ogg" fadeout 1.5 fadein 2.0
n "Eve dönüş yolundasın.{nw}"
n "Eve dönüş yolundasın.{fast} {b}Yalnız.{/b}"
jump son
label son:
stop music fadeout 3.0
if ruh_hali >= 2:
$ renpy.notify("İyi Son ✨")
n "{cps=10}Bazı tanışmalar planlanmaz...{/cps}{w=0.5} sadece olur."
n "İyi bir gündü."
elif ruh_hali == 0:
n "Belki başka bir gün, başka bir kafede."
else:
n "Bir kapı kapandı.{w=0.8} Belki açıktı, sen mi kapadın?"
pause 2.0
n "{size=+6}~ Son ~{/size}"
return
Son Söz
Bu oyunda artık sadece temel komutlar değil, bonus bölümlerindeki özelliklerin çoğunu da kullandık:
Temel
define, default, label/jump, scene/show/hide, menu, if/elif/else, return
Geçişler
fade, dissolve, move, Dissolve(), Fade(), with None trick, offscreenleft
Müzik
play music/sound, fadein, fadeout, volume, if_changed, stop music
Metin Etiketleri
{w}, {cps}, {color}, {b}, {i}, {size}, {nw}/{fast}, {sc}, {fi}, {bt}
Ekranlar (Screens)
screen, show screen, hide screen, vbox/hbox, textbutton, action, Show(), Hide()
Özelleştirme
gui.rpy renk/font/outline, config.name, accent_color
Bonus Özellikler
renpy.notify(), autofocus, offscreen giriş, blend mode katmanı
Bu rehber Visual Novel oyun severler için özenle hazırlandı.
Ren'Py, Tom Rothamel'in açık kaynak projesidir (MIT lisans).