モバイル上の巨大なゲームのためのダウンローダー link

Android や iOS などのプラットフォームには、アプリストアからダウンロードできるアプリのサイズに制限があります。より大きなゲームをサポートするために、ゲーム本体をダウンロードするダウンローダーとしての小さなゲームをRen'Py はサポートしています。

必要条件 link

これを動作させるには、適度な機能を備えた Web ホスティングサービスが必要です。 mega などのアップローダーサービスや itch.io のようなゲームホスティングサイトは機能しません。このダウンローダーは、 Nginx を実行する Digital Ocean droplet と、 10GB を無料でホストできる Cloudflare の R2 でテストされています。

具体的には、Webサーバーはファイルのダウンロードをサポートする必要があり、一度に多くのHTTP範囲リクエストをサポートすると、より適切に機能します。

動作方法 link

このダウンローダーを使用するには、2つのゲームを構築する必要があります。1 つ目はダウンローダーゲームで、Ren'Py エンジンとダウンローダーを含み、自分のモバイルデバイスにユーザーが配信されるものです。

2つ目はメインゲームで、プレイしたいビジュアルノベルです。これがあればダウンローダーゲームによってダウンロードされ、デバイスにインストールされます。

どちらも同じバージョンの Ren'Py でビルドする必要があります - 不一致があればダウンローダーはメインゲームを更新、またはメインゲームのバージョンまで自身を更新します。 Ren'Py アップデーターがモバイルプラットフォームで動作するようになったことで、これが可能になりました。

ダウンローダーゲームが起動すると、メインゲームがインストールされているかどうかが確認されます。インストースされており、バージョンが正しければ、メインゲームが始まります。そうでなければ、ダウンローダーが起動し、プレーヤーにメインゲームをダウンロードするように促します。

メインゲームのビルドとアップロード link

メインゲームに加える必要がある主な変更は、次の行の追加です。

define build.game_only_update = True

options.rpy ファイルの先頭に貼り付けます。これにより、ランチャーのBuild Distribution(配布物のビルド)画面に表示される新しいオプション "Game-Only Update for Mobile" (モバイル用のアップデート専用ゲーム)が追加されます。

"Build Distributions"((配布物のビルド) で、 "Game-Only Update for Mobile"(モバイル用のアップデート専用ゲーム) にチェックを入れます。他のすべてのビルドパッケージのチェックを外します。"Options"(設定)で、"Build Updates"(アップデートをビルド)が設定されていること、および他のオプションが必要に応じて設定されていることを確認します。デフォルトで問題ありません。

次に、ビルド プロセスを実行します。

ゲームのビルドが完了すると、必要なものがすべて揃います。 ''updates.json'', ''updates.ecdsa'' および ''rpu'' ディレクトリにあるすべてのものを Web サーバにアップロードします(rpu ディレクトリが 2 つの更新ファイルの隣にあり、.rpu ファイルが ''rpu'' ディレクトリー内にあることを確認してください。

ダウンローダーゲームの作成 link

ダウンローダーゲームは Ren'Py のゲームですが、サイズは 100MB をはるかに下回るべきです。オープニングシーンや音楽の再生など、小さなゲームでできることは何でもできます。これは個別に作成し、通常の手法を使用して Android または iOS 用にビルドする必要があります。

同時に、プレーヤーにダウンロードするかどうかを尋ね、WiFiに接続していない場合は費用がかかる可能性があることを伝えてから、ゲームをダウンロードする必要があります。

以下は、チュートリアルゲームのアセットを使用したダウンローダーゲームのスクリプト例です。

# The url to updates.json, on your web server.
define URL = "https://www.domain.com/game-updates/updates.json"

# Disable saving in the downloader game.
define config.save = False

define e = Character("Eileen", image="eileen")

label splashscreen:

    scene bg washington
    show eileen happy at left

    $ downloader = updater.start_game_download(URL)

    e "Welcome to the downloader game."

    e "This will download the main game onto your phone, so you can play it."

    if downloader.download_total:
        $ download_mb = int(round(downloader.download_total / 1024 / 1024, 0))

        e "To play this game, you'll need to download [download_mb] megabytes of data. If you're not on WiFi, you could be charged for it. Tap the screen to proceed."

    else:

        e "To play this game, you'll need to download some data. If you're not on WiFi, you could be charged for it. Tap the screen to proceed."

    $ updater.continue_game_download()

これは非常に簡単ですが、いくつかのことがあります。1つ目は、 config.save を False に設定しています。これは、設定を含むセーブとロードを無効にし、ダウンローダーの保存がメインゲームに影響を与えないようにするために重要です。

スプラッシュスクリーンのラベルですべて行って、すぐに起動してゲームメニューへの入力を無効にするするようにしています。

早い段階で、ゲームは updater.start_game_download() を呼び出して、ダウンロードに関する情報を収集しています。この後、ゲームがダウンロードのサイズを確認する間アイリーンにいくつかのことを言わせて時間をつぶします。

プレーヤーが複数回クリックした後、ゲームはダウンロードのサイズを知っている場合もあれば、知らない場合もあるため、条件を使用してダウンロード サイズを確認しています。実数がわかっている場合は、メガバイトに変換されて表示されます。そうでない場合は、より一般的なテキストが表示されます(ゲームのダウンロードサイズの見積もりでもよいです)。

最後に、updater.continue_game_download() が呼ばれ、ダウンロードプロセスが開始されています。スクリーンが表示され、大した操作はできませんが、音楽が再生され、ATL は実行され続けます。

ダウンロードが完了すると、自動的にメインゲームが始まります。失敗した場合、ダウンローダーは再起動し、プレーヤーは再試行できるようになります。

Downloader Screen link

downloader は、ダウンロードの進行状況を示すスクリーンです。デフォルトのスクリーンは renpy/common/00updater.rpy にあり、ゲームディレクトリにコピーを作成してカスタマイズできます。

デフォルトはこちらになります

screen downloader(u):

    style_prefix "downloader"

    frame:

        has vbox

        if u.state == u.CHECKING or u.state == u.PREPARING:
            text _("Preparing to download the game data.")
        elif u.state == u.DOWNLOADING or u.state == u.UNPACKING:
            text _("Downloading the game data.")
        elif u.state == u.FINISHING or u.state == u.DONE:
            text _("The game data has been downloaded.")
        else: # An error or unknown state.
            text _("An error occured when trying to download game data:")

            if u.message is not None:
                text "[u.message!q]"

            text _("This game cannot be run until the game data has been downloaded.")

        if u.progress is not None:
            null height gui._scale(10)
            bar value (u.progress or 0.0) range 1.0

        if u.can_proceed:
            textbutton _("Retry") action u.proceed

style downloader_frame:
    xalign 0.5
    xsize 0.5
    xpadding gui._scale(20)

    ypos .25
    ypadding gui._scale(20)

style downloader_vbox:
    xfill True
    spacing gui._scale(10)

style downloader_text:
    xalign 0.5
    text_align 0.5
    layout "subtitle"

style downloader_label:
    xalign 0.5

style downloader_button:
    xalign 0.5

ダウンローダー関数 link

updater.continue_game_download(screen='downloader') link

ゲームデータのダウンロードを続けます。これは、ダウンロードが完了するか、ユーザーがゲームを終了するまでループします。

updater.start_game_download(url, **kwargs) link

url からゲームデータのダウンロードを開始します。これにより、ダウンロードする必要があるものを決定するプロセスが開始され、 Update オブジェクトが返されます。