Python ステートメント link

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

Python link

The python statement takes a block of Python, and runs the block when control reaches the statement. A basic python statement can be very simple:

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 のステートメントがあります。

The one-line python statement begins with the dollar-sign ($) character, and contains everything else on that line. Here are some example of python one-liners:

# 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

The define statement sets a single variable to a value at init time. For example:

define e = Character("Eileen")

これは以下と等価です。

init python:
    e = Character("Eileen")

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

define character.e = Character("Eileen")

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

define ステートメントを使用して定義された変数は定数として扱われ、セーブロードされないため、変更しないべきです。(Ren'Py はこれを強制しませんが、守らない場合、未定義の動作をします)

default ステートメント link

The default statement sets a single variable to a value if that variable is not defined when the game starts, or after a new game is loaded. For example:

default points = 0

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

label start:
    $ points = 0

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

label after_load:
    $ points = 0

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

default schedule.day = 0

init offset ステートメント link

The init offset statement sets a priority offset for all statements that run at init time. (init, init python, define, default, screen, transform, style, and more.) The offset applies to all following statements in the current block and chold blocks, up to the next init priority statement. The statement:

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!"

will not work, because the variable e is being used as both a character and a flag. Other things that are usually placed into the store are transitions and transforms.

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

その他の名前付き store link

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

Named stores can be accessed by supplying the in clause to python or init python, all of which run Python in a named store. Each store corresponds to a Python module. The default store is store, while a named store is accessed as store.`name`. These python modules can be imported using the Python import statement, while names in the modules can be imported using the Python from statement.

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 に変数名を定義出来ます。

First and Third Party Python Modules and Packages link

Ren'Py can import pure-python modules and packages. First-party modules and packages - ones written for the game - can be placed directly into the game directory. Third party packages can be placed into the game/python-packages directory.

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

pip install --target game/python-packages requests

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

init python:
    import requests

警告

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