Ren'Py 日本語ベーシックガイド

ビジュアルノベル/ノベルゲームエンジン Ren'Py の「これだけ知れば作り始められる」基本機能を、動くコード例つきでまとめたものです。.rpy スクリプトは Python に似た独自言語で、インデント(字下げ)でブロックを表します。最後に「単純な分岐の先でできること」も一覧で載せています。

無料・OSS Python製 Win / Mac / Linux Android / iOS Web (HTML5) セーブ標準装備

クイックスタート(5分で最初の1本)

とにかく動かしたい人向け。下の流れで「画面に出る・喋る・選べる」までいけます。

1. ダウンロード〜起動

  • renpy.org で SDK をDL → 解凍 → ランチャー起動
  • 「新規プロジェクトを作成」→ 名前を入力(例:my_first_vn)→ 解像度はそのままでOK
  • 作ったプロジェクトを選び「スクリプトファイル」→ script.rpy を開く

2. script.rpy を丸ごとこれに置き換え

# ===== キャラ定義 =====
define s = Character("シルヴィ", color="#2563eb")

# ===== 覚えておく変数 =====
default affection = 0

# ===== ここから本編 =====
label start:
    scene bg room with fade          # 背景なければ単色でもOK(後述)
    "目を覚ますと、知らない部屋にいた。"

    show sylvie smile with dissolve  # 立ち絵なければこの2行は消してOK
    s "おはよう。やっと起きたね。"

    $ name = renpy.input("あなたの名前は?")
    $ name = name.strip() or "あなた"
    s "よろしくね、[name]。"

    menu:
        s "朝ごはん、何がいい?"
        "パン":
            $ affection += 10
            s "私もパン派。気が合うね。"
        "ごはん":
            $ affection += 5
            s "渋いね。"
        "まだ寝たい":
            s "だめ。もう昼だよ。"

    if affection >= 10:
        s "今日はいい一日になりそう。"
    else:
        s "……まあ、ぼちぼちいこう。"

    "― おわり ―"
    return

3. 起動して確認

  • ランチャーの「プロジェクトを起動」を押すだけ
  • クリックで読み進む/選択肢を選ぶ/名前入力 → 分岐するのを体験できる
  • セーブ・スキップ・オートはもう動いている(右クリック or 下メニュー)
画像がまだ無くても遊べるscene bg roomshow sylvie smile はその名前の画像が無いとエラーになります。素材ナシで試すなら、その2行を消すか、次のように単色背景にすればOK。
# 画像なしでも動く版(先頭に置く)
image bg room = "#222"            # 単色を背景画像扱いに
# show sylvie smile の行は消しておく
次の一歩:動いたら、下の各セクションで「画像の出し方」「演出」「変数で結末を変える」を足していきましょう。

Ren'Pyとは

Ren'Py(レンパイ)は、ノベルゲーム・ADV・乙女ゲーなどを作る無料・オープンソースのエンジンです。Python製で、シナリオは独自スクリプトで書きます。

  • 出力先:Windows / macOS / Linux / Android / iOS / Web(HTML5)
  • 標準装備:セーブ&ロード・オート・スキップ・バックログ・設定画面が最初から入っている
  • 書く中心game/ フォルダ内の .rpy ファイル
考え方:基本はセリフを並べるだけ。そこに「画像を出す」「音を鳴らす」「選択肢を出す」を足していく積み上げ方式です。

インストール

  • 公式 renpy.org から SDK をダウンロード(OS別)
  • 解凍して Ren'Py Launcher(ランチャー)を起動
  • 「新規プロジェクトを作成」→ 名前を入れる → ひな形が自動生成
  • 「スクリプトファイル」でエディタ(VS Code等)を開いて編集
  • 「プロジェクトを起動」で即プレイ確認
日本語フォント:標準GUIだと日本語が出ないフォントのことがあります。日本語対応フォント(例:Noto Sans JP)を game/ に置いて gui.rpy で指定すると安全です。

プロジェクト構成

新規作成するとだいたいこうなります。最初に触るのは script.rpy

プロジェクト名/
└─ game/
   ├─ script.rpy      ← 本編シナリオ(ここを書く)
   ├─ options.rpy     ← タイトル名・BGM音量などの設定
   ├─ gui.rpy         ← 色・フォント・サイズなど見た目
   ├─ screens.rpy     ← UI画面(メニュー/セーブ画面など)
   ├─ images/         ← 背景・立ち絵などの画像
   └─ audio/          ← BGM・効果音
画像の自動認識images/bg room.png と置くと、スクリプトから scene bg room で呼べます(ファイル名のスペース=画像名のスペース)。

ラベルとセリフ

ゲームは必ず label start: から始まります。ラベルは「シーンの見出し」、セリフは文字列を書くだけ。

label start:
    "むかしむかし、あるところに……"      # ナレーション(話者なし)
    "少女" "ここはどこ?"                  # 一時的な話者名つき
    "……目を覚ますと、見知らぬ部屋だった。"
    return                                # ゲーム終了 / 呼び出し元へ戻る
  • "〜" 1つだけ=ナレーション
  • "名前" "セリフ"=その場限りの話者名つきセリフ
  • よく出る人物は次の「キャラクター定義」で名前を固定するのが定番

キャラクター定義 define

登場人物は define で先に定義しておくと、名前の色や表示が統一できます。ファイル先頭に書くのが通例。

define s = Character("シルヴィ", color="#2563eb")
define m = Character("主人公", color="#0a7d3c")

label start:
    s "おはよう。よく眠れた?"
    m "うん、おかげさまで。"
    s "それはなにより[name]。"     # [変数名] で値を埋め込める
書き方意味
color="#..."名前の表示色
"[変数名]"セリフ中に変数の値を差し込む(名前入力などで)
{w} / {nw}クリック待ち / 待たずに次へ(セリフ内タグ)
{b}太字{/b} {color=#f00}赤{/color}装飾タグ(太字・色・ルビなど)

ジャンプ・コール(流れの制御)

シーンをまたぐにはラベルを呼びます。

label start:
    "プロローグ……"
    jump chapter1          # 戻ってこない移動

label chapter1:
    "第一章。"
    call tutorial          # サブルーチンとして呼んで戻ってくる
    "チュートリアルが終わった。"
    return

label tutorial:
    "(操作説明……)"
    return                  # call の次の行に戻る
  • jump:片道。戻らない
  • callreturn:呼んで戻ってくる(共通シーンに便利)

画像(背景・立ち絵)

背景は scene、立ち絵は show、消すのは hide

label start:
    scene bg room                 # 背景を切り替え(前の画像は全消去)
    show sylvie smile             # 立ち絵を表示(images/sylvie smile.png)
    s "こんにちは。"

    show sylvie surprised at right  # 表情差し替え+右に配置
    s "えっ、もう行っちゃうの?"

    hide sylvie                   # 立ち絵を消す
    "彼女は去っていった。"
整理のコツscene は画面を一旦クリアして背景を敷く、show はその上に重ねる。位置は at left / center / right

トランジション(切り替え演出)

行末に with を付けると効果つきで切り替わります。

    scene bg night with fade        # 黒で一度暗転してから表示
    show sylvie smile with dissolve  # ふわっと出現
    "…時間が流れた。"
    with Pause(1.0)                # 1秒待つ
名前効果
dissolveクロスフェード(重ねて溶ける)
fade黒に落ちて戻る暗転
pixellateモザイク状に切り替え
move立ち絵が位置までスライド移動

音楽・効果音

    play music "audio/bgm_town.ogg" fadein 1.0  # BGM(ループ&フェードイン)
    play sound "audio/se_door.ogg"             # 効果音(1回)
    "扉が開いた。"
    stop music fadeout 2.0                  # BGM停止(2秒かけて)
    queue music "audio/bgm_next.ogg"          # 今の曲の後に予約再生
チャンネルmusic=BGM(自動ループ)、sound=効果音、voice=ボイス。形式は .ogg 推奨。

変数とフラグ(好感度など)

数値や真偽値を覚えさせて分岐に使います。default で初期値宣言、$ で代入・計算。

default affection = 0        # 好感度
default got_flower = False    # フラグ(真偽)

label start:
    menu:
        "花をあげる":
            $ affection += 10     # 好感度+10
            $ got_flower = True
            s "ありがとう、嬉しい。"
        "何もしない":
            $ affection -= 5
default と define の違いdefine=変化しない定数(キャラ定義など)、default=ゲーム中に変化しセーブされる変数。フラグは必ず default

条件分岐 if

覚えた変数で結末を変える。インデントでブロックを表します。

label ending:
    if affection >= 20:
        s "ずっと一緒にいようね。"       # グッドエンド
        jump ending_happy
    elif affection >= 5:
        s "……またね。"
        jump ending_normal
    else:
        s "あなたのことは、もう忘れる。"     # バッドエンド
        jump ending_bad

比較は Python と同じ:== != >= <= > <、組合せは and / or / not

Python連携

Ren'Py の中身は Python なので、必要ならそのまま書けます。1行は $、複数行は python: ブロック。

    $ player_name = renpy.input("あなたの名前は?")
    $ player_name = player_name.strip() or "名無し"
    s "よろしくね、[player_name]。"

init python:                 # ゲーム開始前に関数や定数を準備
    def calc_rank(score):
        if score >= 80:
            return "S"
        return "B"
  • $ x = ...:1行のPython(代入・計算)
  • python::複数行のPythonブロック(実行時)
  • init python::起動時に一度だけ実行(関数定義など)
  • renpy.input():プレイヤーに文字入力させる
これが効く:「中身が全部Python」=普通のゲームロジックは何でも書ける、ということ。次のセクションが本番です。

単純な分岐の“先”にできること

Ren'Py は「セリフ+選択肢」だけのツールではありません。下のどれも標準機能、またはちょっと足すだけで実現できます。気になったキーワードで公式を引くと一気に世界が広がります。

立ち絵を動かす (ATL)
ズーム・回転・揺れ・スライドをアニメで。喋るたびに跳ねる等。
transform / at
表情・衣装の差分合成
体+表情+服をレイヤーで組み合わせ。少ない素材で無限の組合せ。
layeredimage
会話中のサイド立ち絵
セリフ枠の隅に話者の顔。誰が喋っているか一目で分かる。
side image
NVLモード(全画面文)
ADV枠ではなく画面いっぱいに地の文を流す小説スタイルへ切替。
nvl mode
クリックで探索
背景の一部を押すと進むホットスポット。脱出ゲーやマップ移動に。
imagemap / imagebutton
ステータス/所持品UI
HP・お金・アイテム欄など自作UI。育成SLGや乙女ゲーのパラメータ画面。
screen language
ランダム・確率分岐
サイコロ、ガチャ、ランダムイベント。同じ周回でも違う展開に。
renpy.random
ミニゲーム
クリック連打・タイミング・簡易RPG戦闘などをPython+画面で自作。
python / screen
動画ムービー再生
OPムービーやイベントムービーをそのまま流す。プリレンダ演出に。
movie / renpy.movie
パーティクル演出
雪・桜・光の粒を降らせる。背景に重ねるだけで雰囲気が出る。
SnowBlossom
ルビ(ふりがな)
漢字に読み仮名。難読語や演出としての当て字に。
{rb}{rt} ruby
タイプライター表示
文字を1字ずつ表示。緊張感や“間”を演出。
{cps} 文字送り速度
実績・CG/音楽回収
ギャラリー、ミュージックルーム、達成度%、隠しシーン解放。
persistent / gallery
周回特典(2周目)
クリア済みフラグで隠しルート・スキップ短縮・新セリフを解放。
persistent
ボイス/自動ボイス
セリフに音声を紐付け。ボイス音量設定もUIに自動追加。
voice / auto voice
多言語化(翻訳)
セリフを抽出して言語ごとに差し替え。日本語版+英語版を1本で。
translate
分岐の集約管理
多数の選択結果を“今どのルートか”の変数1つに集約して終盤を制御。
フラグ設計
Live2D / 動く立ち絵
Live2Dモデルを読み込んで瞬き・口パク・呼吸。
Live2D 対応
ゲームパッド/アクセシビリティ
パッド操作、読み上げ(self-voicing)、文字サイズ変更が標準。
標準対応
色調・シェーダー演出
回想はセピア、夜は青み、ダメージで赤フラッシュ等の画面加工。
matrixcolor
つまり:単純分岐は入口。Ren'Py は育成SLG・脱出ゲー・カードゲー・RPG風戦闘まで作れる土台で、ほとんどは「Python+画面言語(screen)+persistent」の組合せで届きます。

ちょいレシピ(コピペで雰囲気だけ)

立ち絵を跳ねさせる(ATL)

transform bounce:
    yoffset 0
    easein 0.15 yoffset -30
    easeout 0.15 yoffset 0

label x:
    show sylvie smile at bounce   # 登場でひと跳ね
    s "じゃーん。"

雪を降らせる

    $ snow = SnowBlossom("snowflake.png", count=100)
    show expression snow as snow
    "しんしんと雪が降っている。"

ガチャ的ランダム分岐

    $ roll = renpy.random.randint(1, 100)
    if roll <= 5:
        "激レアイベント発生。"
    else:
        "いつもの朝だ。"

クリアした人にだけ隠しルート(周回特典)

    $ persistent.cleared_once = True     # クリア時に記録
    menu:
        "はじめから":
            jump start
        "真ルート" if persistent.cleared_once:   # 2周目で解放
            jump true_route

セーブ/ロード 標準装備

自分で作る必要はありません。右クリックや画面下メニューからセーブ/ロード/設定が呼べ、バックログ・スキップ・オートも標準で動きます。

  • セーブされるのは default で宣言した変数とシーン進行状況
  • persistent.〜 はセーブをまたいで永続(実績・既読・CG回収率など)

ビルド・配布

  • ランチャー →「ディストリビュートを作成(Build Distributions)」
  • OSごとのzip(Win/Mac/Linux)が出力される
  • Android/iOS は追加SDK設定、Webは「Web向けビルド」で HTML5 出力
  • 容量を抑えるなら画像を適切に圧縮、未使用ファイルは game/ から除く
注意:配布前に「Force Recompile」してから起動し、全ルート・全選択肢が通るか確認を。label の打ち間違いや未定義画像は起動時にエラーで教えてくれます。

早見表(チートシート)

やりたいこと書き方
開始地点label start:
ナレーション"地の文"
セリフs "セリフ"
キャラ定義define s = Character("名", color="#..")
背景 / 立ち絵scene bg 名 / show 名 表情 / hide 名
演出つき切替... with dissolve
BGM / SEplay music "..ogg" / play sound "..ogg"
選択肢menu:"選択肢":... if 条件:で条件表示)
移動(片道/往復)jump 名 / call 名 … return
変数 / 代入default x = 0 / $ x += 1
条件分岐if / elif / else:
文字入力$ n = renpy.input("?")
ランダムrenpy.random.randint(1, 100)
永続データpersistent.名
立ち絵アニメtransform 名:show 名 at 名