Python ステートメント link

Ren'Py は、Python プログラミング言語で書かれており、Ren'Py スクリプトの中に Python のコードを埋め込められます。Python への対応は、フラグの設定から displayable の新規作成まで、様々な場面で利用できます。この章では、Ren'Py のスクリプトから Python コードのステートメントを直接呼び出す方法を説明します。

Python link

python ステートメントは python コードのブロックを取り、制御がそのステートメントまで到達するとそのコードを実行します。基本的な python ステートメントはとても単純です。

python:
    flag = True

python ステートメントは必要ならさらに複雑になります。

python:
    player_health = max(player_health - damage, 0)
    if enemy_vampire:
        enemy_health = min(enemy_health + damage, enemy_max_health)

python ステートメントにはその動作を変更するものが二つあります。 :

hide

hide が与えられると python ステートメントは無名のスコープで python のブロックを実行します。そのスコープは python ブロックが終了すると消失します。

これで python コードに保存されない一時的な変数を使用可能になります。しかしそれはつまり store オブジェクトに直接ではなくフィールドとしてアクセスする必要があるということです。

in

in は名前を取ります。デフォルトの store で実行する代わりに python コードはその名前の store で実行されます。

一行 python link

デフォルトの store で python を一行だけ実行させたいというのはよくあることです。例えばフラグの初期化や更新には一行だけの python が使用されます。 一行だけの python をより便利に記述するために、一行 python のステートメントがあります。

一行 python ステートメントはドル記号 ($) で始まり、その行にコードのすべてを含みます。ここでは 一行 python の例をいくつか示します。

# Set a flag.
$ flag = True

# Initialize a variable.
$ romance_points = 0

# Increment a variable.
$ romance_points += 1

# Call a function that exposes Ren'Py functionality.
$ renpy.movie_cutscene("opening.ogv")

一行 python は常にデフォルトの store で実行されます。

init python ステートメント link

init python ステートメントはゲームロード前の初期化時に python コードを実行します。特にこのコードはクラス、関数の定義やスタイル、設定変数、永続データの初期化に使用されます。

init python:

    def auto_voice_function(ident):
        return "voice/" + ident + ".ogg"

    config.auto_voice = auto_voice_function

    if persistent.endings is None:
        persistent.endings = set()

init 1 python:

    # The bad ending is always unlocked.
    persistent.endings.add("bad_ending")

優先度の値は initpython の間に配置出来ます。優先度が指定されないと、 0 が使用されます。 init ステートメントは優先度の小さいものから大きいものの順に実行されます。 優先度の同じ init ステートメントはファイル名のユニコード順に、各ファイルの開始から終端まで実行されます。

Ren'Py 本体との衝突を防ぐため、開発者は -999 から 999 の範囲の優先度を使用するべきです。 0 以下の優先度は通常ライブラリーやテーマの設定に使用されます。通常の init コードには優先度 0 かそれ以上を使用するべきです。

init python ステートメントは hidein 節も取ります。

init python ブロックで値が設定された変数はその変数が参照するオブジェクトが変更されない限りセーブ、ロードされず、ロールバックにも参加しません。

define ステートメント link

define ステートメントは初期化時、変数に値を設定します。例えば

define e = Character("Eileen")

これは以下と等価です。

init python:
    e = Character("Eileen")

define ステートメントは、ドットと変数名に続けて任意の名前付き store (以下参照) を取れます。例

define character.e = Character("Eileen")

define ステートメントを使用する利点の 1 つは代入が行なわれたファイル名と行番号を記録し、ランチャーのナビゲーション機能が利用可能になることです。

default ステートメント link

default ステートメントは、ゲーム開始時かロード後に変数が定義されていなければその変数の値を設定します。例えば

default points = 0

変数 points がゲーム開始時に定義されていなければ、このステートメントは次と等しいです。

label start:
    $ points = 0

変数 points がゲームロード時に定義されていなければ、次と等しいです。

label after_load:
    $ points = 0

define ステートメントは、ドットと変数名に続けて任意の名前付き store (以下参照) を取れます。例

default schedule.day = 0

init offset ステートメント link

init offset ステートメントは初期化時に実行するすべてのステートメント ( init, init python, define, default, screen, transform, style, など ) に対して優先度のオフセットを設定します。オフセットは現在のブロックとコードブロック内の続くステートメントに次の優先度ステートメントが来るまで適応されます。例

init offset = 42

このコードでは優先度のオフセットを 42 に設定しています。

init offset = 2
define foo = 2

init offset = 1
define foo = 1

init offset = 0

最初の deffine ステートメントは優先度 2 で実行されるので 二つ目の define ステートメントの後に実行されます。 foo は 2 の値になります。

Store の名前 link

Ren'Py が Python 変数を格納するデフォルトの場所は store と呼ばれます。 store で使用する名前が衝突しないかを確認することは重要です。

define ステートメントは値を、それがキャラクターの定義に使用されていても変数に代入します。これはつまりキャラクターとフラグに同じ名前を使用出来ないということです。

以下のコードには欠陥があります。

define e = Character("Eileen")

label start:

    $ e = 0

    e "Hello, world."

    $ e += 1
    e "You scored a point!"

これは変数 e がキャラクターとフラグの両方に使用されているため動作しません。通常 store に格納されるその他の物にはトランジションと変換があります。。

アンダースコア (_) で初まる名前は Ren'Py 内部で使用するものとして扱われます。詳しくは以下を参照してください。 Index of Reserved Names

その他の名前付き store link

名前付きの store はpython コードをモジュールに分ける方法を提供します。モジュールにコードを置くことで、名前が衝突する機会を減らせます。

名前付きの store は in 節を pythoninit python に与えることでアクセス可能で、コードは名前付き store で実行されます。各 store は python モジュールに対応します。デフォルトのstore は store で、名前付きの store は store.`name` でアクセスされます。これらの python モジュールは python の import ステートメントを使用してインポート出来、一方モジュール内の名前は python の from ステートメントを使用してインポート出来ます。

init python in mystore:

    serial_number = 0

    def serial():

        global serial_number
        serial_number += 1
        return serial_number

init python:
    import store.mystore as mystore

label start:
    $ serial = mystore.serial()

名前付きの store はデフォルトの store 同様にセーブロード、ロールバックに参加します。 define ステートメントを使用して名前付き store に変数名を定義出来ます。

本体、サードパーティーの Python モジュールとパッケージ link

Ren'Py は純粋な python モジュールとパッケージをインポートできます。ゲームのために書かれた本体のモジュールとパッケージは game ディレクトリーに直接配置されます。サードパーティーのパッケージは game/python-packages ディレクトリーに配置できます。

例えば必要なパッケージをインストールするために、ゲームのベースディレクトリーに変更してコマンドを実行します。

pip install --target game/python-packages requests

モジュールとパッケージどちらでも init python ブロックからインポート出来ます。

init python:
    import requests

警告

.rpy ファイルで定義された Python コードは、ロールバックで動作するために変換されます。 .py ファイルからインポートされた Python コードは変換されません。そのため、 python コードで作成されたオブジェクトはロールバックで動作しないので、作成後は変更するべきではありません。