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.

18Bölüm
20Hazır Mod
128Repo
6+Platform
ESSH
Bu satırı sen yazacaksın. Bugün başla.
Kuruluma Başla
🆓

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
Kod bilmene gerek yok. Ren'Py'nin kendi basit dili var, bu rehberde öğreneceksin.

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:

Ren'Py Launcher ekranı
Ren'Py Launcher: tüm işlerini buradan yapacaksın

Sol tarafta projelerini görürsün. Sağ tarafta "Create New Project", "Preferences" gibi butonlar var.

Launcher'ın içinde hazır iki proje var: "Tutorial" ve "The Question". İkisini de "Launch Project" ile çalıştırıp göz atabilirsin. Ren'Py'nin neler yapabildiğini görmek için ideal.

İ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.

Proje adı girme ekranı
Proje adını gir, sonradan değiştirebilirsin

2. Çözünürlük

Oyunun ekran boyutu. 1920x1080 veya 1280x720 seç. Emin değilsen 1280x720 ile başla, yeterli olur.

Çözünürlük seçme ekranı
1280x720 çoğu proje için yeterli

3. Renk Şeması

Ren'Py menülerin ve butonların renk tonunu sorar. Birini seç, sonra istediğin gibi değiştirirsin.

Renk seçme ekranı
Vurgu rengi ve arkaplan rengi seç

Tamamlandıktan sonra proje listesinde görünür. "Open Directory" > "game" ile oyun dosyalarının olduğu klasörü aç.

Tüm senaryonu 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:

game/script.rpy: dosyanın tamamı bu olacak, birebir kopyala
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!

Defne
Günaydın! Bugün ne içersin?
Oyuncunun gördüğü ekran: karakter ismi + diyalog kutusu

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.
Girinti kuralı: 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:

game/script.rpy → ÜST BÖLGE: 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")
game/script.rpy → ALT BÖLGE: 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"): d artık "Defne" demek. Yeşil renkte görünecek.
  • d "Metin": tırnak işareti olmadan, direkt d yaz.
  • color="#c8ffc8": ismin rengi. Herhangi bir hex renk kodu koyabilirsin.
Dosyada sıra önemli: define satırları en üstte, label start: onların altında. Karıştırırsan oyun hata verir.
script.rpy dosyasının yapısı şöyle görünmeli:
# ─── 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.

Görseller Nasıl Çalışır?

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.

game/images/ ├── bg_kafe.jpg : arka plan görseli → kodda 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
Büyük/küçük harf fark etmez. Defne_Mutlu.png dosyasını show defne mutlu ile çağırırsın.
Ren'Py oyun içi görünüm: arka plan + karakter + diyalog
Oyunda görseller böyle görünür: arka plan (scene), karakter (show), diyalog kutusu üst üste katmanlanır

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.

sahne (boş)
scene bg kafe
defne
show defne mutlu
show komutu karakteri sahneye ekler

Karakter İ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:

game/images/ ├── defne_mutlu.png : → 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
Kural basit: Dosya adındaki ilk kelime = karakter etiketi, geri kalan = ifade adı.
defne_mutlu.png → karakter: defne, ifade: mutlu
bg_kafe.jpg → tür: bg, isim: kafe
Alt ç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!"
Aynı karakterin farklı ifadesini show ile gösterdiğinde Ren'Py önceki görseli otomatik kaldırır. hide yazman gerekmez.

İstersen alt klasörlere ayırabilirsin:

game/images/ ├── chars/ │ ├── defne_mutlu.png │ ├── defne_uzgun.png │ └── emre_normal.png └── bg/ ├── bg_kafe.jpg └── bg_park.jpg
Alt klasör isimleri (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.

Bilgisayarında Defne_Mutlu.png adında dosya var → kodda show defne mutlu yaz. Hepsi bu.

Dönüşümün adımlarını merak ediyorsan:

Dönüşüm adımları: Defne_Mutlu.png
Defne_Mutlu.png
disk'teki dosya
Defne_Mutlu
uzantı kaldırıldı
defne_mutlu
küçük harfe çevrildi
defne mutlu
_ → boşluk → görsel adı
Örnekler
images/bg kafe.png
bg kafe
images/Defne_Mutlu.webp
defne mutlu
images/chars/defne mutlu.png
defne mutlu
⚠ Alt klasör adı (chars/) yok sayılır, sadece dosya adı önemli

image 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):

Nasıl çalışır
defne-ifade-mutlu.png
disk'teki dosya (tire var, Ren'Py bulamaz)
image defne happy =
"defne-ifade-mutlu.png"
ÜST BÖLGE'ye yaz
show defne happy
artık bu çalışır
# 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.

Desteklenen formatlar:
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:

game/script.rpy → ALT BÖLGE (label içinde, 4 boşluk girintili)
    scene bg kafe
    with fade          # Siyaha gider, yeni sahne gelir

    show defne mutlu
    with dissolve      # Yavaş yavaş belirir
Eski sahne
scene bg kafe
dissolve
geçiş anı
yavaş yavaş erir
tamamlandı
Yeni sahne
scene bg park
dissolve geçişi: eski sahne yavaşça eriyerek yeni sahneye dönüşür

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:

Eşzamanlı vs Ardışık
⚡ Tek with = hepsi aynı anda
scene bg park
show defne mutlu
with dissolve
arka plan dissolve
karakter dissolve
ikisi aynı anda başlar ve biter
🎬 İki with = sırayla oynar
scene bg park
with fade
show defne mutlu
with dissolve
arka plan fade
karakter dissolve
sahne biter → sonra karakter girer
    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 trick: Arka planı sessizce değiştir, oyuncu hiçbir şey fark etmesin. Sonra sadece karakterin belirme animasyonunu göster:
scene bg park
with None
park hazır ama ekranda değişim yok
show defne mutlu
with dissolve
oyuncu sadece bunu görür
Defne zaten park'tayken
belirir gibi görünür
sinematik efekt
    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:

game/script.rpy → ÜST BÖLGE (girintisiz)
# Ü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
game/script.rpy → ALT BÖLGE (label içinde, 4 boşluk girintili)
    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ş."
Gündüz/gece versiyonu yoksa tek arka planla da yapılabilir: arada 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:

game/script.rpy → ÜST BÖLGE (girintisiz)
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
game/script.rpy → ALT BÖLGE (label içinde, 4 boşluk girintili)
    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:

game/script.rpy → ALT BÖLGE (label içinde, 4 boşluk girintili)
    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)
left
center
right
at left  |  at center  |  at right
← 0.0     xalign     1.0 →
Karakterlerin ekrandaki konumları: left, center, right
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:

game/script.rpy → ÜST BÖLGE (girintisiz)
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.
Desteklenen formatlar: OGG Vorbis, Opus, MP3, WAV, FLAC. Ses dosyalarını game/audio/ klasörüne koy. OGG en yaygın ve hafif olanı.
Dosyayı 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
Birden fazla son mu var? Her 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 nedir? Diyalog akışının üstünde çalışan ayrı bir katman. Bir screen tanımlarsın (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)

game/script.rpy → ÜST BÖLGE (girintisiz)
screen secim_ekrani():
    vbox:
        textbutton "Devam Et" action Return(True)
        textbutton "Ana Menü" action MainMenu()
        textbutton "Bir Sahneye Atla" action Jump("sahne3")
game/script.rpy → ALT BÖLGE (label içinde, 4 boşluk girintili)
label start:
    call screen secim_ekrani

Görsel Buton (imagebutton)

game/script.rpy → ÜST BÖLGE (girintisiz)
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.

Hızlı not: 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ı.

game/script.rpy → ÜST BÖLGE'ye default (girintisiz), ALT BÖLGE'ye hikaye (4 boşluk girintili)
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ü. True ise 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:

game/script.rpy → ÜST BÖLGE'ye default (girintisiz), ALT BÖLGE'ye hikaye (4 boşluk girintili)
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.

Değişkenler 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.

Önce şunu anla: script.rpy iki bölgeden oluşur:
┌────────────────────────────────────────────────┐
  ▲ Ü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
En sık yapılan hata: Hikaye değişkenini 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.
$ işareti nedir? 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

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

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

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

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.

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.

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.

# Ö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.01.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.

Ne zaman kullanılır? Karakter tereddüt ediyorsa, sözünü tamamlıyorsa veya bir düşüncenin devamı geliyorsa. Visual novel'larda çok sevilen bir teknik.

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ı:

game/ ├── audio/ : müzik ve ses dosyaları (.ogg, .mp3) ├── cache/ : Ren'Py'nin önbellek dosyaları (dokunma) ├── gui/ : arayüz görselleri (buton, çerçeve vs.) ├── images/ : arkaplan ve karakter görselleri ├── saves/ : oyuncu kayıtları (otomatik oluşturulur) ├── tl/ : çeviri dosyaları ├── gui.rpy : arayüz ayarları (renkler, fontlar, boyutlar) ├── options.rpy : oyun ayarları (başlık, sürüm, build) ├── screens.rpy : ekran tanımları (menü, save, load vs.) ├── script.rpy : ANA SENARYO DOSYAN: buraya yazıyorsun └── *.rpyc : Ren'Py'nin derlediği önbellek dosyaları (dokunma, silme)

En çok dokunacağın dosyalar:

  • script.rpy: tüm senaryon
  • images/: görsellerini buraya koy
  • audio/: müzik ve sesleri buraya koy
  • gui.rpy: görünümü özelleştirmek için
  • options.rpy: oyun başlığı, sürümü vs.
Senaryon büyüdükçe 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.
.rpyc dosyaları nedir?
📄
script.rpy
senaryonu yazdığın dosya: her zaman buraya bak
Ren'Py derler
⚙️
script.rpyc
otomatik oluşturulur, daha hızlı yükleme için
✅ Bu dosyalara dokunmana gerek yok. Ren'Py kendisi yönetir.
.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.

Kısa özet: Hikaye akışı → 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)
Varsayılan ekranları değiştirmek için screens.rpy'yi aç ve ilgili screen bloğunu düzenle. Sıfırdan yazmana gerek yok, mevcut olanı özelleştir.
Screens & Screen Language tam referansı: Ren'Py Screens Documentation (resmi, İngilizce).

Ö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.

Dosya nasıl eklenir / değiştirilir? Proje klasörünü bilgisayarında aç, istediğin dosyayı sürükle-bırak veya üzerine yaz. Ren'Py başlarken bu klasörleri tarar:
  • game/images/ → arkaplan ve karakter görselleri
  • game/gui/ → arayüz görselleri (diyalog kutusu, butonlar, menü arka planı)
  • game/audio/ → müzik ve ses efektleri
  • game/ veya game/fonts/ → özel font dosyaları (.ttf, .otf)
Dosyayı koyduktan sonra oyunu başlat veya Shift+R ile yeniden yükle. Değişiklik anında görünür.
Ren'Py ana menü
Ana menü: gui/main_menu.png değiştirilerek özelleştirilmiş
Ren'Py diyalog ekranı
Diyalog ekranı: textbox.png ve namebox.png ile şekillendirilmiş

VN Arayüzü: Hangi Parça Nereden Geliyor?

gui/main_menu.png: ana menü arka planı
images/ klasörü → show ile çağrılır
Defne
↖ gui/namebox.png
"Günaydın! Bugün ne içersin?" Metin gui/textbox.png üzerine çizilir.
GeriAutoSkipGeçmişKaydetYükleTercihAna Menü
gui/namebox.png: karakter adı kutusu
gui/textbox.png: diyalog alanı
gui/button/: hızlı menü butonları
gui/main_menu.png: arka plan

gui/ Klasör Haritası

Proje oluşturulduğunda otomatik gelen dosyalar, bunları değiştirerek arayüzü şekillendir:

game/gui/ ├── main_menu.png : Ana menü arka planı (tam oyun çözünürlüğü) ├── game_menu.png : Save/Load/Ayarlar overlay arka planı (genellikle daha koyu) ├── textbox.png : Diyalog kutusu arka planı ├── namebox.png : Karakter adı kutusu arka planı ├── window_icon.png : Görev çubuğu simgesi (32×32 veya 64×64 px) ├── button/ │ ├── idle_background.png : Normal buton görünümü │ ├── hover_background.png : Üzerine gelinince │ ├── selected_idle_background.png : Seçili durum │ └── selected_hover_background.png : Seçili + üzerine gelince ├── bar/ : İlerleme çubukları (ses seviyesi göstergesi vb.) ├── scrollbar/ : Geçmiş paneli ve menülerdeki kaydırma çubukları └── slider/ : Ses/hız sliderları
Bir dosyayı değiştirmek için: aynı isimde ve aynı boyutta yeni bir PNG'yi üzerine yaz. Ren'Py başlarken 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

game/gui.rpy

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ı
Renk formatı: Hex kodu kullan: '#e84855'. Saydamlık eklemek istersen sonuna 2 hane daha ekle: '#e8485580'. Son iki hane saydamlığı belirler: 00 = tamamen şeffaf, FF = tamamen opak.
Ren'Py renk ve font özelleştirmesi sonucu
Renk, font ve metin boyutu ayarları uygulandıktan sonra oyun böyle görünüyor

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.

Türkçe harf desteği için Noto Sans önerilir, ç, ğ, ı, ö, ş, ü karakterlerini sorunsuz gösterir.
game/gui.rpy
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)

game/gui.rpy

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
]
Parametreler:
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

game/gui/textbox.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.

✅ Her şekil yapılabilir ❌ Boyut tam uymalı ✅ Tasarımcı dostu ❌ Renk değişince yeni PNG lazım

Yöntem 2: Kod (yuvarlatılmış köşe)

game/gui.rpy

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.

✅ Görsel editör gerektirmez ❌ Sadece dikdörtgen + yuvarlak köşe ✅ Renk tek satırda değişir ❌ PNG ile çakışırsa PNG kazanır
# 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
PNG boyutu: oyununun genişliği × textbox_height. 1280×720 oyun için 1280×185 piksel. İkinci yöntemi kullanıyorsan textbox.png dosyasını sil, yoksa PNG öncelik alır.
Ren'Py özelleştirilmiş diyalog ekranı
textbox.png, namebox.png ve renk ayarları uygulandıktan sonraki diyalog görünümü

İsim Kutusu

game/gui/namebox.png + game/gui.rpy

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  ·  game/gui/game_menu.png

game/gui/main_menu.png

Oyun açılınca çıkan ilk ekranın arka planı. Logo ve butonlar bunun üstüne bindirilir.

✅ Herhangi bir görsel olabilir ❌ Tam çözünürlük olmalı (1280×720)

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.

✅ Main menu'den bağımsız ❌ Çok parlak olursa yazılar kaybolur
Boyut oyunun çözünürlüğüyle uyuşmalı. Yanlış boyut görüntüyü uzatır veya keser.
Ren'Py oyun menüsü (About ekranı)
game_menu.png değiştirildikten sonraki Hakkında ekranı: Kaydet/Yükle/Ayarlar aynı arka planı kullanır

Buton Görünümleri

game/gui/button/

Menü butonları (Yeni Oyun, Kaydet, Yükle vb.) dört durumda farklı görüntü gösterebilir. PNG'leri bu klasöre koy:

Yeni Oyun
idle_background.png
normal durum
Yeni Oyun
hover_background.png
üzerine gelince
✓ Seçili
selected_idle_background.png
seçili durum
gui/button/ ├── idle_background.png : normal buton arka planı ├── hover_background.png : üzerine gelinince ├── selected_idle_background.png : seçili buton (ayarlar sayfasındaki seçenekler vb.) └── selected_hover_background.png : seçili + üzerine gelince
✅ Her buton ayrı tasarlanabilir ❌ Dosya yoksa Ren'Py kendi gri renkleriyle doldurur ✅ Sadece idle + hover koysan yeterli ❌ Boyut tüm dosyalarda aynı olmalı
Ren'Py ayarlar ekranı özelleştirilmiş butonlar
Buton görselleri değiştirildikten sonraki Ayarlar (Preferences) ekranı

Karakter Adı Rengi

game/script.rpy (Character tanımı)

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.

Geliştirici modu kapalıysa bu kısayollar çalışmaz. 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:

Ren'Py NVL modu
NVL modu: metin tüm ekranı kaplar, roman okuma hissi verir
# 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 Yeniden Oluşturma: Launcher'da "Generate GUI" butonu 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:

Seçenek butonu normal
choice/idle_background.png: normal durum
Seçenek butonu hover
choice/hover_background.png: fare üzerindeyken
Ren'Py seçenek ekranı
Özelleştirilmiş seçenek ekranı: buton görselleri değiştirilmiş, arka plan ve renk uyumlu
# 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:

Ana menü overlay
main_menu.png üstüne overlay bindirilmiş, sol taraf karartılarak butonlar okunur
Oyun menüsü overlay
game_menu.png üstüne overlay, sağ panel butonlar ve ayarlar için
gui/overlay/ ├── main_menu.png : Ana menü overlay (genellikle soldan sağa gradient) ├── game_menu.png : Oyun menüsü overlay (sağ panel karartması) └── confirm.png : Onay ekranı (çıkış/kayıt üstü) arka planı
Overlay'ler saydam PNG. Karartmak istediğin bölgeyi siyah + yarı saydam yap, geri kalanı tam saydam bırak. Gradient kullanırsan geçiş doğal görünü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:

Kayıt slotu normal
slot/idle_background.png: normal durum
Kayıt slotu hover
slot/hover_background.png: fare üzerindeyken
Ren'Py kayıt ekranı
Özelleştirilmiş kayıt ekranı: her slot kendi ekran görüntüsünü ve tarihini gösteriyor
# 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:

Ren'Py slider ayarlar
Slider'lar: ses seviyesi, metin hızı, otomatik ilerleme süresi
Ren'Py scrollbar geçmiş
Scrollbar: geçmiş ekranında dikey kaydırma çubuğu
gui/slider/ ├── horizontal_idle_bar.png : Slider arka plan (normal) ├── horizontal_hover_bar.png : Slider arka plan (hover) ├── horizontal_idle_thumb.png : Sürükleme noktası (normal) └── horizontal_hover_thumb.png : Sürükleme noktası (hover) gui/scrollbar/ ├── vertical_idle_bar.png : Scrollbar arka plan (normal) ├── vertical_hover_bar.png : Scrollbar arka plan (hover) ├── vertical_idle_thumb.png : Sürükleme noktası (normal) └── vertical_hover_thumb.png : Sürükleme noktası (hover)

Skip ve Bildirim Göstergesi

Oyuncu diyalogları atladığında veya ekranda bir bildirim çıkması gerektiğinde bu görseller kullanılır:

Ren'Py skip ve bildirim
Sol üst: skip göstergesi (atlatma modu açık). Sol alt: bildirim popup'ı (renpy.notify ile tetiklenir)
gui/ ├── skip.png : "Atlatılıyor..." göstergesi arka planı └── notify.png : Bildirim popup arka planı
# 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:

Ren'Py onay ekranı
Onay ekranı: gui/overlay/confirm.png arka planı, Frame ile çerçevelenmiş
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 tanımı
Borders(25,5,25,5): köşe boyutları
Borders ölçeklenmiş
Aynı PNG genişletilmiş: köşeler bozulmadan
Borders tiled
tile=True: kenarlar tekrarlanarak dolduruluyor
# 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)
Borders sistemini anlamak çok önemli. Tek bir 100px'lik buton PNG'si ile 200px, 400px, 800px genişliğinde butonlar yapabilirsin, köşeler hiç bozulmaz.
Tüm 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?

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.

Tüm kütüphanelerin kapsamlı listesi: awesome-renpy (336+ yıldız, 290+ kaynak)

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.

game/libs/ nedir? Bu klasördeki dosyalar diğer tüm .rpy dosyalarından önce yüklenir. 3. parti kütüphaneleri buraya koy, kendi kodunla karışmaz.
Dikkat: ZIP'lerdeki 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+DReload. 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.

Örnek: ChromaGlitch bir karaktere uygulamak için script.rpy'ye şunu yaz:
    show defne mutlu
    show expression Glitch("defne mutlu") as glitch_char  # bu satırı ekle
    d "Ne oluyor?!"
📦

20 mod, hepsi ücretsiz ve kopyala-yapıştır kurulumu

Aşağıdaki modların tamamı tek bir .rpy dosyası veya klasör kopyalayarak kurulur. Karta tıkla, kodu gör ve direkt kullan.

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.

S3 stüdyo çatışmasıbeat drop anıkavga & gerilimkötü son kapısı
    # 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
⚙ Parametreler
offsetDilim kayma miktarı (piksel). Yükseldikçe daha sert glitch. varsayılan: 30
randomkeyNone = her renderda farklı görünür. Sabit değer = hep aynı glitch desenini üretir. varsayılan: otomatik
chromaKromatik aberasyon (RGB kayması) açık/kapalı. varsayılan: True
minbandheightBir dilimin minimum piksel yüksekliği. Küçük = çok ince dilimler. varsayılan: 1
timeout_base(animated_glitch) Glitch titreme hızı saniye cinsinden. 0.08 = çok hızlı. varsayılan: 0.1
ChromaGlitch önizleme
🎨

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.

S6 klüp patlamadarbe anımüzik doruk noktası
    # 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.

trip / halüsinasyonsarhoşluk sahnesirüya geçişimetin tag olarak da çalışır
    # 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
⚙ Parametreler. WaveShader() sınıfı
amplitudeDalga yüksekliği (piksel). Büyük değer = daha sert bozulma. varsayılan: 10
frequencyDalga sıklığı. Yüksek = çok dalgalı, sıkışık görüntü. varsayılan: 10
speedAnimasyon hızı çarpanı. 2.0 = iki kat hızlı. varsayılan: 1.0
parallelWaveShader() 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 sahnesianı & geçmişretro klip izlemeVHS estetik
    # 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.

S8 Demir telefon sahnesiprojeksiyon / hologramuzaktan iletişim
game/libs/holo/
    # 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ığı
⚙ Parametreler: script başına tanımla
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.9
interalphaÇizgiler arası saydamlık. Düşürdükçe tarama efekti güçlenir. varsayılan: 0.75
blinkingTitreşim/yanıp sönme sıklığı. 0.0 = hiç, 1.0 = sürekli. varsayılan: 0.5
lineheightTarama çizgilerinin kalınlığı (piksel). varsayılan: 4
Hologram efekti
🎭

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 sokak ışığıkaranlık oda atmosferigece sahnesi tonurenk overlay
    # 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.

aktif karakter vurgususeçim / hover efektineon çerçeve estetik
    # 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.

stüdyo yangınıklüp sahne sıcağıduman efektidramatik final
    # 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
⚙ Parametreler. DoomFire(width, height)
widthEfektin genişliği (piksel). Sahne genişliğini (1280 veya 1920) ver. zorunlu
heightAteş şeridinin yüksekliği. 200 = normal alev, 400 = büyük yangın. zorunlu
fire_multAteş yoğunluğu çarpanı. 1.0 = normal, 2.0 = daha güçlü alev. varsayılan: 1.0
KonumlandırmaAteşi ekranın altına sabitlemek için: show … at bottom veya ypos 0.8

RenPyParticles: Parçacık Sistemi GitHub ↗

Özel sprite tabanlı parçacık sınıfı. Sahneye canlılık ve hava katmanı verir.

konser konfetisiyağmur gece sahnesiklüp duman & tozışık zerreleri
    # 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.

shift + tilt + zoomlerp smoothingMatrix.rotate

Ren'Py'nin Creator-Defined Displayable (CDD) sistemiyle fare pozisyonunu takip eden özel bir displayable. Her frame'de:

  1. Fare pozisyonu -1..1 aralığına normalize edilir
  2. Lerp ile ani atlamalar önlenir
  3. Görsel %12 büyük render edilir (kenar görünmesin)
  4. Matrix.rotate() ile 3D perspektif eğimi
  5. 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")
⚙ Ayarlanabilir Değerler
shiftFare takibinde kayma miktarı (piksel). Yüksek = daha dramatik. varsayılan: 40
tilt3D perspektif eğimi (derece). 0 = eğim yok. varsayılan: 3.0
smoothLerp hızı. Düşük = daha yavaş/yumuşak takip. varsayılan: 0.05
script.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:

Lila fareyi gezdirin
Lila, BG'den bağımsız hareket ediyor: arka plan 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.

nefes salınımfare kaymadouble-lerp
    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")
⚙ Ayarlanabilir Değerler
shiftFare kayma miktarı. BG'nin shift'inden çok düşük tutulmalı (derinlik farkı). varsayılan: 5
breath_amountNefes zoom genliği. 0.004 = %0.4 salınım. varsayılan: 0.004
breath_speedNefes hızı (Hz). 0.3 = ~7 saniye döngü. varsayılan: 0.3
script.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.

ana menüpasif beklemeambient efektneon UI
# ── 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()
⚙ Uyarlamak için
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, mavi
outlinesYazı etrafındaki ışık halesı. absolute(3) = kalınlık, #0044cc60 = renk+saydamlık. varsayılan: 3px mavi glow
Frame("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çeve
alpha 0.25 / 0.75Aura parlamanın min ve max yoğunluğu. varsayılan: 0.25 – 0.75
⚔️

Kılıç Kesme Efekti

3 katmanlı kılıç (çizgi + parlama + iz) → karartma → ekran flaşı + sarsıntı → buton ikiye ayrılıp uçar.

ana menü girişiboss revealsinematik başlangıçaksiyon oyunu menüsü
# ── 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
⚙ Uyarlamak için
kilic_cizgi / parlama / iz3 katman: beyaz çizgi (10px) + cyan parlama (60px) + mavi iz (120px). Renk/kalınlık ayarlanabilir. varsayılan: #fff / #66ddff / #3399ff
rotate -42Kılıç açısı. -30 = sığ hamle, -45 = dik çapraz. Tüm kilic_* image'larda aynı değer. varsayılan: -42
linear 0.10Kılıç geçiş süresi. 0.06 = çok hızlı, 0.15 = yavaş. 3 katman 0.02s arayla gelir. varsayılan: 0.10
ekran_sarsinmaVuruş sonrası ekran sarsıntısı. easein 0.03 × 5 kare. Offset değerlerini azalt/artır. varsayılan: ±14px
jump 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.

neon ışık efektidramatik karanlıkkontrast artırmacyberpunk atmosferyağmur + parıltı
game/libs/blend-modes/

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.

Ne işe yarar? Mesela arka planına ayrı bir ışık dokusu koyarsın. 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
Doku ne? İkinci parametredeki PNG bir renk veya desen dosyası, sen hazırlıyorsun. En basiti: GIMP/Photoshop'ta 1280×720 tek renkli PNG yap (#ff6600 turuncu = gün batımı tonu, #001133 lacivert = gece). game/images/'e koy, adını yaz.
⚙ Hangi mod ne yapar
screenIşık bindirme: arka plan üstüne parıltı, neon glow
overlayKontrast güçlendirme: koyu alanlar daha koyu, açık alanlar daha açık
soft_lightYumuşak overlay: gün batımı, sabah atmosferi
lightenİki görselden daha açık olanı gösterir, doğal aydınlatma
darkenİki görselden daha koyu olanı gösterir, gece, gölge
color_burnKaranlık alanları yoğunlaştırır, sert noir tonu
color_dodgeAçık alanları patlatır, ışık bombası, güneş efekti
differenceRenklerin farkını gösterir, ters/negatif etki
exclusionDifference'ın yumuşak hali, hayal gibi tuhaf ton
vivid_lightÇok güçlü kontrast, yıldırım, enerji patlaması
Aa

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.

okunabilirlikneon UIcyberpunk diyalogkaranlık arka plan
game/gui.rpy
# 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
]
⚙ Format: (kalınlık, renk, x_offset, y_offset)
kalınlıkpiksel. 1–2 = okunabilirlik, 4+ = glow efekti
renkhex renk, sonuna 2 hane saydamlık eklenebilir: #00000088 = %50 opak
x_offset / y_offsetçizgiyi kaydır. 0, 0 = çevreden eşit, 2, 2 = sağ-alt gölge
Birden fazla katmanlisteye virgülle ekle, her katman ayrı render edilir, glow efekti bu şekilde yapılır
💬

Kinetic Text Tags: Animasyonlu Metin GitHub ↗

En popüler metin efekt kütüphanesi. Diyalog tag'leri olarak çalışır, kod gerektirmez.

duygusal patlama anıçılgın/sarhoş karakterbağırma diyaloğusistem mesajıtüm sahnelerde kullanılabilir
    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ş
⚙ Tüm Tag Listesi
{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
Kinetic Text Tags önizleme

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.

S4 Demir DM sahnesiS8 gece mesajlarıgıyabi karakter konuşmasısosyal medya DM
    # 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.")
Messenger Emulator önizleme
🔔

Multi-Notify: Bildirim Popup'ları GitHub ↗

Birden fazla bildirim aynı anda yığılır. Sosyal medya akışı varmış hissi verir.

viral olma anıyeni takipçi bildirimimesaj yağmurubaşarım + DM aynı anda
    # 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.

ilk kayıt tamamlandıDemir'le tanışmaviral sontüm sonlar açıldı
    # 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.

karakter profillerirap dünyası sözlüğügizli lore sayfalarıtanışma sonrası kilit açma
    # 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ı.

konser CGkarakter close-up anlarıfinal sahne görselleribonus içerik
    # 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.

soundtrack koleksiyonuNeon Cross albüm odasıhikaye ilerledikçe parça kilit açma
    # 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.

Discord presencesahne adı gösterimioyun süresiücretsiz tanıtım
    # 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..."
Discord Presence önizleme

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.

sinematik zoomkonser pan çekimikarakter close-up geçişitüm sahnelerde değer katar
    # 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.

tüm çok-karakterli sahnelerS5 sözleşme masasıS9 çatı sahnesiotomatik çalışır
    # 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
⚙ Parametreler: options.rpy'de tanımla
autofocus.dimPasif karakterlerin karartılma miktarı. 0.0 = hiç, 1.0 = tamamen siyah. varsayılan: 0.5
autofocus.blurPasif karakterlerin bulanıklaştırılma miktarı (piksel). 0 = sadece karartma. varsayılan: 2.0
autofocus.durationKonuşmacı değişiminde geçiş süresi (saniye). varsayılan: 0.3
autofocus_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.

göz kırpma idlenefes alma animasyonukonuşma ağız senkronuasset varsa sıfır kod
Bu mod asset gerektirir. Çalışmak için özel bir spritesheet PNG dosyası lazım: animasyonun tüm kareleri yan yana tek bir görsel. Sadece kodu kopyalayıp yapıştırmak yetmez; dosya olmadan ekranda hiçbir şey görünmez. Hazır bir spritesheet yoksa bu modu henüz kullanamazsın.
Spritesheet nedir? Karakterin 4 göz kırpma karesi varsa bunları tek bir PNG'de yan yana (4 sütun, 1 satır) sırala. Mod bu dosyayı alır, kareleri sırayla oynatır.
    # 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
⚙ Parametreler
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: 4
rowsSpritesheet'teki dikey satır sayısı. Tek sıra animasyon = rows=1. örnek: 1
frame_timeHer karenin ekranda kalma süresi (saniye). Küçültünce animasyon hızlanır. örnek: 0.15

Geliş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ı

Ü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.

Karakter sprite'ı aramak için itch.io'da şu filtreyi kullan: Assets → Characters → Free → Ren'Py. "Top rated" sıralayınca en kaliteliler gelir.

🌆 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.

Lisans kontrolü: "Ücretsiz" her zaman "ticari projede kullanılabilir" anlamına gelmiyor. İndirmeden önce lisans kısmını oku. CC0 = tamamen serbest. CC-BY = atıf gerekli. "Free for non-commercial" = para kazanıyorsan ödeme gerekebilir.
En hızlı yol: itch.io'da "Top rated" sıralayıp "Free" filtrele. Topluluğun kaliteli bulduğu şeyler hep üstte çıkar.

Ö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.

karakter yerleştirmesahne düzenifareyle düzenlemeen çok kullanılan araç
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.

sahne önizleme
+
bg pin
+
karakter pin
sag ust: koordinatlar
Sol Panel — Layer Listesi
- scene0
  - master
    + camera ← dokunma
    + bg ← dokunma
    - lila ← bunu sec
      + Child/Pos
      + 3D Matrix
      + Anchor/Offset
      - Zoom/Crop
Orta — Timeline
Mavi cubuk = zaman imleci
Elmas = keyframe
Cubugu surukle → zamanda ilerle
Bir layer secili iken deger degistir → o zamana keyframe duser
Sag Panel — Butonlar
show image pins — pinleri ac/kapa
scene editor — sahne ayarlari
remove keys — secili keyframe'leri sil
clipboard — kodu kopyala
close — kaydetmeden kapat
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.

Pin'ler üst üste mi? Arka plan ve karakter aynı noktadaysa (ikisi de xpos=0.5) pin'leri ekrandan sürükleyemezsin, hep alttaki layer'ı (bg) yakalar. Çözüm: karakterin 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üğü
Child/Pos (Konum)
xpos — yatay konum (0.0–1.0)
ypos — dikey konum (0.0–1.0)
zpos — derinlik (genelde 0)
xaround/yaround — dönme merkezi
radius/angle — dairesel hareket
Zoom/Crop (Boyut)
zoom — genel büyüklük (1.0 = normal)
xzoom — yatay ölçek (−1 = ayna)
yzoom — dikey ölçek
cropX/Y/W/H — kırpma alanı
Anchor/Offset
xanchor/yanchor — pivot noktası
xoffset/yoffset — piksel kaydırma
3D Matrix
rotate — 2D döndürme (derece)
matrixcolor — renk efektleri
alpha — saydamlık (0–1)
Shift+P = pozisyon editörü · Shift+K = kamera (sahne zoom/pan) · Shift+A = animasyon (keyframe hareketler)
İpucu: Basit karakter girişleri (sağdan gel, sola çık) için Action Editor'e gerek yok — Ren'Py'nin 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.

arayüzana menükaydet/yükleayarlar ekranı
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
ÖNCE (varsayılan)
Oyun Adı
Yeni Oyun
Devam Et
Ayarlar
Çıkış
SONRA (özelleştirilmiş)
Oyun Adı
Yeni Oyun
Devam Et
Ayarlar
Çıkış
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.

kod editörüsözdizimi renklendirmeotomatik tamamlamaşart
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 PreferencesText EditorVisual 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.

script.rpy · VS Code
1
2
3
4
5
6
7
8
label baslangic: scene bg kafe show barista mutlu b "Hoş geldin! Ne alırsın?" menu: "Türk kahvesi":
Launcher'ın kendi editörü çok basit: renklendirme yok, otomatik tamamlama yok, hata bulma yok. VS Code kurmak 5 dakika ama yazma hızını ikiye katlar.
🗺️

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.

hikaye haritasıdal görselleştirmesenaryo analizigeliştirici aracı
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
start
kafe_sabah
barista_sohbet
son_iyi
park_yuruyus
son_kotu ⚠️
🟣 = script.rpy · 🟢 = sonlar.rpy · ⚠️ = çıkmaz (jump yok)
10+ label'dan sonra hangi sahnenin nereye gittiğini kafadan takip edemezsin. Bu araç dallanmaları görselleştirir, çıkmaz sokakları yakalar.
📱

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.

telefon sahnesimesajlaşmamodern VNkarakter iletişimi
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"
K
Kai çevrimiçi
Neredesin?
Yoldayım.
Çabuk gel.
yazıyor...
Mesaj yaz...
📎
Modern VN'lerin vazgeçilmezi. DDLC, Mystic Messenger gibi oyunlar bu tarz telefon sahneleriyle ünlü. Oyuncuya "gerçek telefon" hissi verir.
🏆

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.

başarım popupoyuncu motivasyonuSteam uyumlugizli son
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
[ oyun sahnesi devam ediyor ]
🏆
İlk Adım
İlk seçimini yaptın.
Oyun devam ediyor...
Steam'de yayınlayacaksan bu eklenti Steam Achievements ile de entegre olabiliyor. Detaylar GitHub sayfasında.
💬

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.

köşe bildirimiipucuarka plan mesajıhafif popup
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."
[ oyun sahnesi ]
🏆 Başarım: İlk Adım
📍 Bölüm 2: Park
🔑 Anahtar bulundu!
Yerde bir anahtar var. Cebime attım.
Ren'Py'nin yerleşik 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.

Ren'Py topluluğu, bitmiş küçük oyuna bitmemiş büyük projeden çok daha fazla değer veriyor. "Demo" bile olsa yayınla.

☕ Ö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.

Oyunun adı: Kahve Molası  ·  Süre: ~3–4 dakika oynanış  ·  Öğreteceği: karakter tanımı, sahne, sprite, geçiş, müzik, menü, değişken, koşul, gece geçişi, metin efekti, dağıtım build'i.

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

Kahve Molası | Hazır Asset Paketi

Bu oyun için gereken tüm görseller ve müzik tek ZIP'te. İndir, game/ klasörüne aç, kodlamaya başla.

3 arka plan + 1 karakter sprite + 1 müzik · 3.6 MB
⬇ Asset Paketini İndir

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.

Kendi görsellerini kullanmak istersen Ücretsiz Varlıklar bölümündeki kaynaklardan indir. Müzik için Free Music Archive veya Pixabay Music'e bak. MP3'ün varsa convertio.co'dan OGG'a çevir.

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.

game/script.rpy → ÜST BÖLGE (girintisiz)
# --- 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 nedir? "Bu karakter hep aynı kalacak" demek. Oyun boyunca Lila hep Lila, ismi değişmeyecek. O yüzden 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.

game/script.rpy → ÜST BÖLGE: define satırlarının hemen altına yaz (girintisiz)
# --- Değişkenler ---
default ruh_hali = 0
Neden 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.
Şu ana kadar script.rpy şöyle görünmeli:
# --- 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.

game/script.rpy → ALT BÖLGE: 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.jpg dosyasını arka plan yapar. Ekrandaki her şeyi siler, sadece bunu gösterir.
  • with fade: siyahtan açılır. Geçişler bölümündeki fade efekti.
  • 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.png dosyasını sahneye ekler. scene'in aksine arka planı silmez, üstüne ekler.
  • at center: Ortaya konumlanır. at left veya at right da var.
  • with dissolve: Sprite yumuşakça beliriyor. fade ekranı karartır, dissolve sadece değişen şeyi karşıtırır: karakter girişi için doğru olan budur.
🎯 Pozisyonu ince ayarlamak istersen: 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
$ ne demek? Satır başındaki $ "bu satır Python kodu" anlamına gelir. $ ruh_hali += 1 = değişkeni 1 artır.
jump ne yapıyor? Hikayeyi başka bir bölüme (label'a) atlat. Burada iki farklı dala ayrılıyoruz.

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
{sc=2} = Kinetic Text Tags modunun titreme (scare) efekti. Lila'nın kelimesi titreyerek çıkar, tereddüt hissi verir. (Mod kurmadıysan bu etiketleri sil, metin normal görünür.)
İ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ıysa ruh_hali 2 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}"
{w=0.8} → 0.8 saniye bekleme, dramatik duraklama.
{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
volume 0.6 → Kafe müziği %60 seste çalar, arka planda kalır.
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ı

game/gui.rpy: bu satırları bul ve değerlerini değiştir
# 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
text_outlines → Metnin etrafına siyah 2px çizgi koyar. Kafe arka planı açık renkli olsa bile yazı kaybolmaz.
accent_color → Tüm buton çerçeveleri, seçili öğeler bu renge döner. Tek satırla tüm arayüz renklenir.

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:

game/gui.rpy: gui.text_font satırını bul, 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"
Türkçe karakter desteği şart. Google Fonts'tan indirirken "Turkish" subset'i destekleyen bir font seç. Öneriler: Noto Sans Turkish, Nunito, Quicksand, Comfortaa. Dosya adında boşluk olmasın.

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/ klasöründe şu dosyaları değiştir
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.

Görsel hazırlamaya üşeniyorsan renk ve saydamlığı 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:

game/gui.rpy: menü buton ayarları
# 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.

Template kullanırken dikkat: ZIP içindeki 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:

game/ klasörüne kopyala
# 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:

game/script.rpy → ÜST BÖLGE (define'ların yanına, girintisiz)
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."
)
game/script.rpy → ALT BÖLGE (ilgili label'ların içine ekle)
# 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"
with None → with move: Karakter önce görünmeden ekran dışına konur, sonra 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:

📄 script.rpy tam dosya · bonus özellikler dahil
# ═══════════════════════════════════════════
# 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 oyunu çalıştırabildiysen, Ren'Py'nin hem temellerini hem ileri tekniklerini öğrendin demektir. Şimdi sıra kendi hikayende. Geliştirici Araçları bölümündeki Console ve Developer modunu açarsan saatler içinde test ederek geliştirirsin.
🎮
ESSH
Rap sanatçısı · Fullstack developer · Oyun yaratıcısı.
Bu rehber Visual Novel oyun severler için özenle hazırlandı.

Ren'Py, Tom Rothamel'in açık kaynak projesidir (MIT lisans).