見出し画像

非プログラマのRen'Pyノート:オートセーブ+続きからロードするスクリプト

Ren'Py(以下renpy)は色々カスタマイズできる上にアップデートしても崩れにくい強いノベルゲームエンジン。しかし流石にセーブロード周りはやや堅牢な作りになっているっぽい印象です。簡単に変更できたら素人こと私のような者がうっかり触ってしまいバグの温床になりかねませんからね。

そもそも、オートセーブクイックセーブ手動セーブあり、セーブスロットたっぷりあり、どこに不満がありましょうか。

……だがそれを承知でカスタマイズしたい! そんな私のようなワガママ開発者のために、セーブロード周りをカスタマイズする方法のうち、単スロット状にする方法をまとめました。

主に、カジュアルゲームにあるような

-特定/指定の箇所でオートセーブされる
-オートセーブ箇所からデータを呼び出せる
-なのでいわゆる単スロットっぽくなる仕組み
-セーブロードスロットの表示はない(概念はある)

……状態にする手順を紹介します。

この方法は、シミュレーションやランダムアイテムなど、セーブ&ロードによるリセマラが非推奨のゲームとは相性が良いかと思います。反面、ロールバックとの相性はめちゃくちゃ悪いので、対策を本記事終盤に記載しております

まず全文載っけときます

renpyあんましよくわからないです。という方のために全文載っけときます。変更箇所はscript.rpy(他のファイルでも良い)とscreen.rpyです。解説を読みたい人は1.以下をご確認ください。

script.rpy に以下コピペー

#終了時にオートセーブしない
define config.autosave_on_quit = False
#選択時に自動保存する
define config.autosave_on_choice = True
#勝手に自動保存させないぞ
define config.autosave_frequency = False 
#多分あった方がよい 知らんけど
define config.has_autosave = True

#メニュー画面で一番最初に表示される画面を指定(後程解説
define _game_menu_screen = "preferences" 

#永続データ(これがないと、ビルドデータにセーブデータが残ってしまう)後程解説
default persistent.firstsave = False

#背景の変化でわかりやすくするため色背景を用意
image color_blue = Solid("#0f59a2")
image color_orng = Solid("#d8652b")
image color_gray = Solid("#252525")   

label start:
    scene color_blue
    "テスト。セーブするよ。ここでビルドデータの続きからがアクティブになってないか確認してね。"

    scene color_orng
    $ renpy.force_autosave()
    $ persistent.firstsave = True    
    "テスト。セーブした。ロードするとここから始まるはず。"    

    "セーブ耐久テスト。2回目。"
    $ renpy.force_autosave()

    scene color_blue
    $ renpy.force_autosave()      
    "セーブ耐久テスト。222222222222"

    scene color_orng    
    "セーブ耐久テストおわり。始まるとしたら22222って書いているところから。"

    scene color_gray
    "セーブできたか、フォルダを確認。データをロードできるかボタンを押してみてね"

    "おわり"

screen.rpy の以下箇所を書き換える(上書き)

screen navigation():

    vbox:
        style_prefix "navigation"

        xpos gui.navigation_xpos
        yalign 0.5

        spacing gui.navigation_spacing

        if main_menu:

            textbutton _("スタート") action Start()

            textbutton _("続きから") action FileLoad(1, confirm=True, page="auto")

        else:

            textbutton _("ヒストリー") action ShowMenu("history")

            #textbutton _("セーブ") action ShowMenu("save")

クイックメニューを使う人は、クイックセーブのセーブロードも併せてコメントアウトしてね。

以下、上記の解説です。わからなくても動けば良いという方は飛ばしてもいいかも知れない。

解説1.オートセーブ周りの設定を準備

デフォルトのままですとrenpyオートセーブ設定をそのまま使うことになり、

-一定の時間が経過すると自動セーブされる
-タイトル画面に戻ろうとすると自動セーブされる

……という状態です。これを変更するには以下のようにどこかに書き込みます。start以降(ゲーム本体部分)「ではない」なら大体どこでもいいようですが、わからない方はscriptの label start:より上に書いておきましょう。

#終了時にオートセーブしない
define config.autosave_on_quit = False
#選択時に自動保存する
define config.autosave_on_choice = True
#勝手に自動保存させないぞ
define config.autosave_frequency = False 
#多分あった方がよい 知らんけど
define config.has_autosave = True


#メニュー画面で一番最初に表示される画面を指定(後程解説
define _game_menu_screen = "preferences" 

#永続データ(これがないと、ビルドデータにセーブデータが残ってしまう)後程解説
default persistent.firstsave = False

この辺はお好みでご変更ください。私は「指定した場所でオートセーブ」+「選択肢時に自動セーブ」、「タイトル画面に戻る際はオートセーブしない」にします。

解説2.メニューからアクセスできないようにする

次に、セーブロードにアクセスできない状態にします。書かれている箇所は「screen.repy」でセーブ、ロードを検索し関連箇所をコメントアウト。

        if main_menu:

            textbutton _("スタート") action Start()

        else:

            textbutton _("ヒストリー") action ShowMenu("history")

            #textbutton _("セーブ") action ShowMenu("save")#コメントアウトしちゃう

        #textbutton _("ロード") action ShowMenu("load") #コメントアウトしちゃう

なお「Load and Save(セーブ・ロード)スクリーン」もヒットしますが、一旦無視します。

クイックメニューの方が残ってると台無しなので、繰り返しますがクイックメニュー使う方はそちらも同様にコメントアウトすれば、プレイヤーはどこからもセーブロードを呼び出せなくなります。

スロット自体が消失したわけではなくプレイヤーからアクセスする手段がなくなった……はずなのですが、

だがセーブ画面が表示されるのだが?!

これは、メニュー画面を表示する際、デフォルトでセーブ画面が表示されるよう指定されているためです。いったいこの設定はどこをどうさわればいいのかまるっきりわかりません。そんな時はTwitterの #renpy疑問 タグで助けを求めるに限りますね。

まあでもなんか難しそうだしこれは無理かな……。

ウワーおかげさまで3時間後に解決しました!!

上記スクリプトだとデフォルトの表示がロード画面になるわけなんですけど、例えば「環境設定」を表示させたいなら「preferences」、操作説明なら「help」と書けばOK。

define _game_menu_screen = "preferences" #メニュー画面で一番最初に表示される画面を指定

解説3.続きからボタンを作るorメニューで表示

その辺に野良ボタンで置きたい場合は以下ご参考ください。上記同様、ゲーム本体「以外」の場所に書けば呼び出せます。

screen button():#命名がヒドイですね……
    vbox:
        align (0.5, 0.5)
        #textbutton _("続きから") action FileLoad(1, "None") 
        textbutton _("続きから"):
            text_size 48
            action FileLoad(1, confirm=True, page="auto")
            #最初にNone入れるのはダメ。autoは怪しいが……(10回以上はダメと言ってる人がいる?)
            #最初にNameを入れないとエラーが出る。quick,autoでなければ整数?
            background "color_gray"

#背景の変化でわかりやすくするため色背景を用意
image color_blue = Solid("#0f59a2")
image color_orng = Solid("#d8652b")
image color_gray = Solid("#3f1212")   

呼び出したい場所(label start 以降=ゲーム本体)で、以下のように書けばOKです。

    call screen button 
    #showだとボタン外を押すと進行するのでcallと使い分けてね

しかし、そんな使い方をする方は少なく、おそらく一番多いのはメインメニュー(タイトル)画面から選びたいんじゃないかな〜と思います。なので、2で書いたscreenの、メニュー該当箇所に追加で以下のように書き加えます。

        if main_menu:

            textbutton _("スタート") action Start()

            textbutton _("続きから") action FileLoad(1, confirm=True, page="auto")
            #最初の1というのはファイルネーム。これがないと怒られる。1が合ってるかどうかは分からないです(すいません
            #confirm というのは、小窓で本当にいいのかい? と聞くやつ。Falseなら聞かず進行
            #pageは、どこかを指定しないとダメっぽい。通常ページを指定したかったが名前がわからなかった……

        #以下略

するとメニューに「続きから」が表示されます。

ところで、余談ですがこのあたりなんかビルドしたら押せなくなったり、逆にセーブデータがないはずなのに呼び出せたりして、どうにかするのにめちゃくちゃ苦労しました……。この記事書くのだけだと30分〜1時間くらいなんだけど、ここまでたどり着くのに3〜4日かかってます。辛かった。

解説4.適切な場所で保存する

ではセーブテストをしてみましょう。ここで、永続データというのを使いましょう。これにより、永続データtrue以降は続きからを呼び出せるようにします。

なおこれなしでテストする(たぶんmacだけかも)と、ビルドしてもセーブデータが残ってて呼び出せる恐怖を味わう可能性があるので念の為入れましょう。

label start:
    scene color_blue
    "テスト。セーブするよ。ここでビルドデータの続きからがアクティブになってないか確認してね。"

    scene color_orng
    $ renpy.force_autosave()
    $ persistent.firstsave = True #永続データとはこれです    
    "テスト。セーブした。ロードするとここから始まるはず。"    

    "セーブ耐久テスト。2回目。"
    $ renpy.force_autosave()

    scene color_blue
    $ renpy.force_autosave()      
    "セーブ耐久テスト。222222222222"

    scene color_orng    
    "セーブ耐久テストおわり。始まるとしたら22222って書いているところから。"

    scene color_gray
    "セーブできたか、フォルダを確認。データをロードできるかボタンを押してみてね"

    "おわり"

これまた合っているか全然わからないのですが、上記のように書くと保存されます。ちゃんとデータが保存されたかどうかは、📁save フォルダを見ればわかります。

呼び出せるようになりました。

……で、終わりではなく、ここで終わってしまうと、上述のようにビルドしたデータでもセーブデータが残って呼び出せてしまう恐怖を味わうことになる可能性があるので、screen.rpyの続きからボタンに「永続データがtrueでない場合は表示しないよ」を入れておきます。

正確には、開発PC本体に残っているセーブデータを呼び出せてしまう状態に「私の開発環境では」なった。というだけの話なのですが、初心者こと私がつまづきがちなポイントなので、永続データできちんと処理していた方が心臓に優しいです。この項目がなんのことかよくわかる方は対策しなくて大丈夫です、renpyがちゃんと処理してくれるはずです

        if main_menu:

            textbutton _("スタート") action Start()

        elif persistent.firstsave:
            textbutton _("続きから") action FileLoad(1, confirm=True, page="auto")

これで、start 以下の行を通過しないと続きからボタンは有効になりません。最初のオートセーブ直後に入れておきます。

    $ persistent.firstsave = True #永続データとはこれです  

「ボタンが有効ではない場合も表示されて欲しい」人は、以下ご参考ください。

##「無効の選択肢を表示する」にはこれをどこかに書く############## 
define config.menu_include_disabled = True


ロールバックを無効にする

冒頭で書きましたとおり、本システムはシミュレーションやランダムアイテム取得など「遡るとズルやリセマラができて、本来のゲームの楽しみを奪ってしまう」のを防ぐ手立てとしては非常に有用ですが、renpyにあるロールバック機能とは相性が悪いです。

ノベルパート「以外」の場所ではロールバックできないようにするスクリプトを適切な箇所に仕込んでテストしましょう。

$ config.rollback_enabled = False #これを書いたより「前」にはロールバックできない

私はシミュレーションパートが始まる直前や終わった直後、オートセーブの直前などに仕込んでいます。


カスタマイズの注意点

私が調べた限りでは10年ほど前の記事で「強制オートセーブでは、オートセーブを10回以上セーブすると呼び出せなくなるかも」みたいなこと言ってる人がいたので、繰り返しセーブロード耐久テストをしていただく、ビルドデータを作って試してみる、などおすすめします。

自分も色々やってみてる最中なのでまた何かわかれば追記しますが、もしお気づきの点あればご指摘いただけると嬉しいです。


この記事が気に入ったらサポートをしてみませんか?