Skip to main content

イカッチャでビッグラン向けのステージを遊ぶための方法

About 3 min

イカッチャ

通常、イカッチャにおけるサーモンランのモードは次のうちのどちらかです。

  1. プライベート
  2. レギュラー
項目プライベートレギュラー
条件レギュラー以外いつものバイトのシナリオ保存
編成緑ランダムのみ(自由選択可)固定
ブキ固定変動
キケン度200%まで任意
オカシラシャケ出現しない任意
レアブキ枠なしあり

大まかに分けると上のような違いがあります。レギュラーで遊ぶためにはオンラインで「いつものバイト」をするか「いつものバイト」のリザルトをシナリオ保存する以外に方法はありません。それ以外の遊び方をすれば必ずプライベート扱いになります。

一応、ビッグラン開催時はいつものバイトをすればビッグラン扱いになりますがシナリオが保存できないため確認できないのでここでは割愛します

レギュラーの場合は編成は固定されており、シナリオで遊んだとしてもたとえ緑ランダムであってもブキを変えることができません。一方、プライベートの場合は他人のシナリオコードを保存した場合などはブキが表示されていることがありますが、内部的には全て緑ランダム(任意)扱いのため、自由にブキを変えることができます。

プライベートとレギュラーの違い

また、プライベートでレギュラーと似たようなバイトを再現しようとしても以下のような違いがあります。

  1. オカシラシャケが出現しない
  2. ブキを選択した場合、選択したブキで固定される
    • レギュラーでは編成四種からランダムにローテーションですが、プライベートの場合は選択したブキで固定です
  3. ランダム枠でクマサン印のレアブキが支給されない

更に、イカッチャの場合は

  1. 「クマサン」が「ナゾの声」になる
  2. バイト終了後のクマサンからのメッセージがない
  3. イカリング3にリザルトが登録されない

の違いがあります。要するに、レギュラーのフリをしてリザルトを提出することはできません。ズルはダメということです。

シナリオ

シナリオはバイトを再現するための必要最低限の情報をまとめたものです。シナリオはクマサン商会の端末からシナリオコードを入力して取得するか、自分のリザルトから発行することでセーブデータに書き込むことができます。

保存できるシナリオの上限は50です

また、プライベートバイトは通常、キケン度を200%までしか上げることができないため、200%以上のキケン度のシナリオがあるならそれは必ずレギュラーのシナリオになります

通常はビッグランのバイトをシナリオとして保存することはできませんが、データを書き換えることにそのようなデータを作成することは可能です。

シナリオのデータ

セーブデータとして書き込まれているシナリオの情報について解説します。

ここで解説しているものに加えて、ハイスコアも記録されていますがめんどくさいので割愛します。

モード

  1. レギュラー
  2. プライベート
  3. チームコンテスト
  4. コンテスト
  5. ビッグラン

の五つのモードが存在します。一時期、イカリング3ではPRIVATE_SCENARIOというモードが存在していましたが、現在はなくなって単純にPRIVATEに統一されました。

ランダムシード

支給ブキ、スペシャル、出現するオオモノシャケの種類と順番などのありとあらゆるWAVEの内容を決定するシードです。

ステージID

ビッグランを含む、全てのステージの中から任意の一つ。

キケン度

四人の内部的レートの平均なので、キケン度x5の値となる。

キケン度200%なら1000、キケン度333%であれば1665の値が入っている。

シナリオコード

NPLNサーバーから発行された値。シナリオとシナリオコードは一対一関係であるだけなので、意味のある値ではなかったりする。

オカシラシャケ

シーズン4時点ではヨコヅナ(23)またはタツ(24)のみが有効。ランダム設定もあるかも知れないが、不明。

実は出現しない(0)という値も有効。プライベートの場合はオカシラシャケが出現しないので常に0になっています。

モードがプライベートの場合は後述するオカシラメーターの値を20(出現率100%)に設定しても出現しません。

ただし後述するが0という値は意味がない

バージョン

シナリオを保存したときのスプラトゥーン3のバージョン。ここが現在のバージョンよりも低いと「正しく再現されないかも知れません」的な警告が表示されます。

タイムスタンプ

最後にそのシナリオを遊んだ時間。

オカシラメーター

四人の合計の値。一人あたりの最高値は5なので合計20が最高で、20に設定すれば100%、EX-WAVEが発生します。

レアブキ

ランダム枠で20%の確率で選ばれるクマサン印のブキの種類。

0を指定するとレアブキが支給されず、プライベートの場合は常にこの値は0になっています。

シーズンID

シナリオを保存したときのシーズン。ランダムブキの抽選で必要になる値。

例えば、シーズン3までのランダム編成のシナリオでは何度遊んでもシーズン4で実装されたフィンセントは絶対に支給されません。

ここのシーズンチェックの判定が誤っているため、保存したシナリオのシーズンとモードによっては選択したブキに関わらずボールドマーカーが支給されてしまうというバグが発生します。

有効性チェック

0か1が入っています。

0にするとその他全てのパラメータの値に関わらずそのシナリオが無効になり、選択することができなくなります。

よって、基本的には1を入れておいて良いパラメータです。

シナリオの有効性

有効性チェックとは別にシナリオの有効性チェックがあります。

というか、多分シナリオをセーブから読み込んだときに特定の条件を満たすと有効性チェックが上書きされています。

以下、シナリオが無効になってしまうパターン

  1. モードがレギュラーでもプライベートでもない
    • モードは五種類ありますが、この二つ以外は無効になります
  2. レギュラーでオカシラシャケIDが0になっている
    • オカシラシャケが出現しない可能性のあるレギュラーのバイトは存在しないのでエラーになります
    • オカシラシャケを出現させたくない場合はオカシラメーターを0にしましょう(出現率0%)
  3. ビッグラン用のステージを選択する
    • 未確認ですが、多分そう
  4. レギュラーでレアブキIDが0になっている
    • 未確認ですが、多分そう

というわけで、一般的にはビッグランのステージを遊ぶことはできません。

それもこれもisValidの値が上書きされてしまうからなので、それを無効化するためのパッチの開発に取り組んでいました。

このパッチが完成すれば本来は弾かれているはずのシナリオを遊ぶことができ、楽しいことになるはずです。が、意外と難しかったのでこちら方面での対応は行き詰まっていました。

パッチをつくろう

で、いろいろあってめんどくさいなということで放置気味だったのですが「ビッグラン用のステージ、ステージのパラメータを変えれば遊べますよ」という情報を頂いたので、自分でもパッチを作ってみることにしました。

ステージのパラメータ

サーモンランのステージ情報は/RSDB/CoopSceneInfo.Product.400.rstbl.byml.zsというファイルの中に書き込まれています。

  • DisplayOrder
    • 並び順です
  • Id
    • 内部ID(数値)です
  • isBigRun
    • ビッグラン用のステージかどうかのフラグ
  • Season
    • 開放されたシーズン
  • __RowId
    • 内部ID(文字列)

ステージに設定されているデータはこの五つです。サーモンランの部屋を立てたときに選択可能であるかどうかはisBigRunDisplayOrderで制御されていそうな気がするのでこれらを弄ってみることにします。

ビッグラン用のステージはisBigRun=TrueDisplayOrder=-1となっていてどちらかを使って非表示にされている可能性が高い

解析する

となればサーモンラン用のステージ情報であるCoopSceneInfo.Product.400.rstbl.bymlを読み込んでいるところをバイナリを解析して探します。

これは検索すればすぐに見つかって、バージョン4.0.2であればsigned __int64 __fastcall sub_14CEBE4(CoopSceneInfo *a1, unsigned __int16 **a2)であることがわかります。

また、このとき0番目の引数であるCoopSceneInfoの構造体は以下のような定義になっています。

struct CoopInfo {
    _QWORD __rowId;
    _DWORD displayOrder;
    _DWORD id;
    _DWORD season;
    _BYTE isBigRun;
}

これだけだとわかりにくいと思うのでポインタを表示すると、

00000000 CoopSceneInfo
00000000 __rowId
00000008 displayOrder
0000000C id
00000010 season
00000014 isBigRun
00000015 undefined
00000016 undefined
00000017 undefined

になります。後半3バイトは謎の値が入っていますがまあそれはどうでも良いです。

やりたかったことは、ステージのビッグラン設定を無効化することなので、CoopSceneInfoのインスタンスのポインタをa2とすれば

a2->isBigRun = 0;

となるわけですが、アセンブラではこのような書き方はできず直接ポインタをいじるしかないので、a2のポインタが格納されているレジスタを仮にX2とすれば、

STRB XZR, [X2, #0x14]

XZRは読み込めば常に0が返る、魔法のようなレジスタです、便利

のようなコードを書けば良いことになります。ここまでできれば答えは出たも同然ですね。

isBigRunは1バイトの情報しか持たないので(真理値なので1ビットでも良いような気もするがそのような命令がなさそう)、32ビットの値をコピーするSTRではなく8ビットコピーのSTRBを使いましょう。

よって、上記のアセンブラはゼロレジスタを読み取って64ビットの長さの0を読み込んで、下位8桁をX2[0x14]に代入する、という内容になります。

32ビットコピーがSTR、半分の16ビットコピーがSTRH(Half)なので8ビットコピーはSTRB(Binary)なのだろうか

ちなみにXZRの代わりにWZRを使えば32ビットの0が返ります

こうすることで、ファイルからステージ情報を読み込んだ段階でisBigRunの値を強制的に0(False)で上書きすることができます。

注意点としてはステージ情報をファイルから読み込むのは起動直後のブート画面(黄色と青のインクのところ)で、一回しか読み込まれないためEdizon形式のパッチではこの方法は利用できません。

あとはこれをIPSwitch形式に変換すればOKです。DisplayOrderも変更する必要があるかと思ったのですが、こちらは特に不要でした。

パッチの効果

最後にパッチの効果と制限を書いておきます。ホストがパッチを当てている必要があるのは言うまでもないので、クライアントがパッチを当てているときと当てていないときで挙動がどう変わったかをメモしておきます。

モードパッチ未パッチ
レギュラーOKNG
プライベートOKOK
ビッグランNGNG

とあるように、パッチを当てた本体がホストになれば部屋を立ててビッグラン用のステージを選択できるようになり、ビッグラン用のステージが設定されたシナリオを読み込むことができるようになります。

ステージが選択可能なものかどうかはホストしかチェックしないため、ホストがパッチを当てているだけでビッグラン用のステージは遊べます。

実はスプラトゥーン2でも初期はステージの整合性チェックはホストしか行っていなかったが、ある時からクライアントもチェックするようになった

ただし、以下の制限があります。

  1. モードとしてビッグランは指定できない
    • レギュラーまたはプライベートを選択してください
  2. プライベートを選択した場合、強制的に緑ランダムになる
    • プライベートバイトの仕様上、そうなります
    • クマサン印のレアブキは支給されません(シナリオ自体に設定すればいけるかも)
    • オカシラシャケは出現しません(オカシラメーター20を設定しても出現しません)
  3. レギュラーを指定した場合、クライアントもパッチを当てている必要があります
    • パッチを当てていない場合、ゲーム開始直後に通信エラーが発生します
    • 任意のブキやクマブキを使いたい場合は全員がパッチを当てている必要があります

よって、未パッチのユーザーと遊びたい場合はモードをプライベートにする必要があります。通常の金ランダムであれば普通に未パッチのユーザーとも遊べるだけに、ビッグランだけ弾かれてしまうのがちょっと悲しいですね。

記事は以上。

Last update:
Contributors: tkgstrator