悟茶辞苑ッ

ごちゃのはなまる備忘録

TAS用エミュレータの機能紹介

TASに興味がある人、機能に興味があるエミュレータ開発者の人に知ってもらえればと思います。そのうちきれいにまとめてTASLaboにおいてみたいです*1

知っている人にとっては今さらなものが多いかと思いますが、最後の方の機能は意外と実態が知られていないかもしれません。なお、すべてのTAS用エミュレータがここに書かれているすべての機能を有しているわけではありません(じつを言うと使ったことのない機能の説明も書いています)。興味がある方はぜひ実装されていない機能を実装して、そのソースコードをコミュニティに提供してください (>ヮ<)

エミュレータのの実物に触れたい人は、Emulator resources / Homepagesを覗いてみるとよいです。親階層のEmulator resourcesからもさまざまな情報が得られるので、興味がある人は覗いてみるがよいです。また、TASVideos / Emulator Resources / Featuresは幾分違った分け方でカテゴリ分けして、幾分違った感じの説明をしています。こちらも興味のある方はぜひ。

用語

必要そうなものだけあらかじめ簡単に説明しておきます。

エミュレータ(emulator)

多くは語りませんし、面倒なので尋ねないでください。まったく知らない人のために、アプリケーションの雰囲気のみ簡単にお伝えします。

ここで言うエミュレータは、ゲーム機本体の代わりをするアプリケーションのことです。スクリーンショットから見て取れるように、だいたいはメニューとゲーム画面からなるシンプルな外観を持ちます。

コントローラ入力はPCゲームのように、キーボードあるいはジョイスティックでおこないます*2。その他の補助機能は一般のアプリケーションのように、メニューから項目を選択したり、ショートカットキーを用いたりして使います。

ちなみに、エミュレータと区別して、本物のゲーム機は実機(console)と呼ばれます。

フレーム(frame)、フレームレート(framerate)、FPS(frames per second)

これらの用語は、一般の動画の世界で言われるのと同じ意味で用いられます。フレームというのは動画を構成する最小単位で、秒間のフレーム数をフレームレート、FPSと呼びます。これらの意味合いに関してはフレームレート用語解説 - アニメのフレームレートまとめwikiその他多数のサイトに解説があると思います。

通常、1フレームはコントローラの入力が読まれる最小間隔であり、操作の最小間隔です。TASがフレームという単位を重要視する理由はここにあるのです。TASで言う1フレームは何秒程度のものなのか、すなわち各種ゲーム機のフレームレートに関しては誰しも疑問に思うことかと思いますが、これに関しては「1フレーム = 1/60秒」と覚えておけばまず問題ありません。厳密なことを言えば60.0とは限らないのですが(NTSC/PALの相違、60は近似値であり実機とは異なるなど)、まずそういう問題に関わる機会はないかと思います。

TASVideosに実機やエミュレータのフレームレートに関するトピックが立てられたことがあります。より詳細な数値が知りたい人は参考にするとよいでしょう。

desync(同期ずれ)

エミュレータの不具合で、動画記録時の状況を動画再生時に再現できないこと。多くの場合、その原因はステートの不十分さにあります。「ステートセーブ・クイックセーブ」の項を参照。

基本(有名どころ)

ステートセーブ・クイックセーブ(savestate, quicksave)

エミュレータを使ったことがある人なら誰もが知っていると言っても過言ではない機能。「どこでもセーブ」という俗称の通り、好きな箇所でゲームの状態を保存・読込することができます。なにかミスをしてしまっても、その直前でセーブしておけば、とっさにそこからゲームをやり直すことができるというわけです。保存されたどこでもセーブのデータのことはステート(state、savestate)と呼びます。動画記録中に作成されたものをmovie snapshotと呼ぶこともあります。

言わずもがなTASに必須の機能で、TASの代名詞とも言えるものかもしれません。ゲームをロードして動画の記録を途中からやり直すことを「追記(rerecording)」、動画を記録するにあたっておこなわれた追記の合計回数を「追記回数(rerecord count)」と呼ぶのが一般的です。

ステートに記録される内容が不十分だと、動画記録時の状況を再生時に再現できず、内容のずれからプレイが狂ってしまうことがしばしばあります(同期ずれ、desyncと呼ばれる)。ずれることが経験的に認知されていてさえ、開発者がその詳細な原因を突き止めることはしばしば困難であることが多いため、開発者・利用者双方にとってdesyncは悪魔のような存在です。運が良ければ記録されたキーのタイミングを少しずらすだけで解決できますが、ゲームの進行に乱数が大きく関わる場合など、修正困難な状況の方がおそらく多数を占めていることでしょう。

ステートに関してはこれ以外にもdesyncを発生する要因があります。たとえば特定の動画を記録している最中に動画と関係ないステートを読み込んでしまったら、動画の記録はそこで狂ってしまいます。動画記録に特化したエミュレータでは、こうした人為的なミスに対する防止措置も積極的に取られていることが多いです。desync対策は動画記録用エミュレータの使命です。

動画記録(movie recording)

ここで言う動画はaviやflvなどの一般のマルチメディアファイルのことではなく、コントローラの入力操作を延々記録したエミュレータ独自の動画形式(キームービー)のことです(例: fcm, smv, vbm)。混同を避けるため、前者をvideo、後者をmovieと呼ぶ場合が多いように思います。リセットも記録できることが望ましいです。

コントローラの入力のほか、必要であればセーブデータ(SRAM)を含むことができます*3。また、エミュレータに記録タイミングに影響を与えるような設定項目がある場合は、それらの設定の記録時の状況も埋め込みます。

記録した動画を他の人と共有するためにアップロードする場合があります。TAS動画制作者の間では、キームービー専用のアップローダMicrostorageを利用するのが一般的です。体系がシンプルで、時間が経過してもファイルが残り続けるためです。

スロー(slowdown, slow motion)

ゲームの動作速度を通常より低い割合に落とします。機能としては実装されている場合がほとんどですが、TAS動画制作には利用しません(基本機能に入れたのはまず間違いなく実装されているという理由から)。代わりにframe advanceを用います。

コマ送り(frame advance、フレームアドバンス、1フレ入力)

フレームに関しては冒頭に説明したとおり、動画記録の最小時間単位です。Frame advanceは1フレームだけゲームを動作させて、エミュレータをポーズ状態にする機能、いわばコマ送り機能です。国内でも英語の名称がそのまま(あるいはカタカナ書きで)用いられることが多いです。(国内において)チャット等の比較的省略表現が用いられやすい場では、しばしばFAと略されることもあります。

追記と並んでTASに必須の機能です。追記とframe advanceがあれば、いかにもTAS動画らしい見た目の動画を作ることは誰にでも可能です。難しいのは「最速」のレベルまでそれを突き詰めることなのです。

高度なエミュレータではラグフレームをスキップする機能を有していることもあります。ラグの認識に関しては後述のラグカウンタの項で説明します。

早送り(fast forward)

可能な限り高速にゲームを動作させます。テレビ番組の合間のCMを早送りして飛ばすのと同じように*4、長いデモシーンを飛ばすのに便利です。時折ターボと呼ばれることもありますが、連射機能との混同を避けるためかあまり耳にしません。

意外に思われるかもしれませんが、TAS動画制作でも重宝される機能です。TASで扱われる動画ファイルには基本的にコントローラの入力しか記録されておらず、途中状況は含まれません。動画を先頭から再生しないことには、ある一時点の状況の再現はできないのです(以前に動画を再生したことがあり、あらかじめシーク用のステートが作成してある場合は別として)。「1時間の地点まで動画を記録したけれど、わけあって30分の時点からやり直したい」と思ったとき、10倍速で再生できれば3分で30分時点にたどり着けますが、高速化する手段がなければ30分の時間をシークに費やさなければいけません。ね、必要でしょう?

ボタンを押している間早送りするタイプと、ボタンを押すたびに等速・高速の切り替えをするタイプがあります。どちらも実装されていると使い分けもできて便利です。

連射機能

ここで述べるのはエミュレータ自身の持つ連射機能です。時折ジョイパッドが連射機能を有していることがありますが、TAS動画制作における利用は推奨されません。

ボタンを押して、離してという一連の操作をエミュレータが自動的におこなうようになり、隙のない正確な連射が可能になります。通常1フレーム間隔(60fps時秒間30連射)の連射をおこないますが、エミュレータによってはこの間隔を設定することもできます。

一般的なプレイの感覚からすると、特定のキーを押している間、連射状態が持続される機能を想像することかと思いますが、TAS用途ではキーを押さない状態で連射状態を保つ機能も存在します。これに関してはAutofireの項で説明します。

高度なエミュレータではラグフレームをスキップして連射する機能を有していることもあります。ラグの認識に関しては後述のラグカウンタの項で説明します。

TAS Input Plugin

TAS方面の人でも何の話かと思ってしまうかもしれませんが、対象ゲーム機によっては重要なのでここで紹介してしまいます。

スクリーンショットニンテンドー64のTAS Input Pluginの動作例です(フォーラムから引用)。N64のコントローラにはアナログスティックがついています。いかに自由なタイミングで入力ができてもそこはアナログ、理想的な角度と強さを入力するのは容易ではありません。そこで、コントローラを用いる代わりにパラメータを数値入力する方法を提供してくれるのがTAS Input Pluginです。

TAS Input Pluginというのは広く普及している一般名詞というよりは、上述のN64用入力プラグイン固有の名称という感じです(そもそもこのような機能が必要な機種が、現状ではN64以外にないと思われます)。

※プラグイン:知っている人にとっては常識かもしれませんが、N64PSXなどのエミュレータGPU、SPU、CDR処理など、各処理をプラグイン(DLL)として実装させ、エミュレータ本体はそれらを束ねることで動作するようになっています。こうすることで、本体の修正なしにゲーム・環境に応じた好きな実装を組み合わせて使うことができるのです。上記のTAS Input PluginはN64のPADプラグインの一種なのです。

メモリ関連機能

最近は準必須機能となりつつあるメモリ関連の主な機能をご紹介します。

メモリウォッチ(Memory Watch)

現代TAS制作には欠かせない、メモリ上の値を表示するための機能です。ゲーム機も中身はコンピュータ、内部ではプログラムがいろいろな処理をしては、メモリ領域に対してさまざまなデータを読み書きします。プレイヤーからは見えないような敵キャラクターの残り体力なども、メモリはすべて知っています。そういう表からは見えない数値をプレイヤーに見えるよう表示させる機能がMemory Watchなのです。ちなみに国内での呼び方もメモリウォッチや原語アルファベット表記が主流かと思われます。メモリビューアと呼ぶのは別の機能と混同する可能性もあるので悩ましいところです(本質的にはどちらも同じですが)。

目的の数値が格納されているメモリ上のアドレス(場所)を指定して、値を表示させます*5。アドレスと値だけではなにを意味するデータなのかわかりづらいので、併せてコメントが書けるようになっていることが多いです。目的とする数値が格納されている変数のアドレスを探すためには、一般的にはMemory Searchが使われます(同名の項を参照)。また、改造・改造コード関連のサイトから調べられることもあります。

こういった機能で表示させるものはさまざまですが、主にはキャラクターの位置と速度、体力、ゲーム内部の時間、乱数などがあります。スーパーマリオワールドは、メモリ上の速度を表示させないと最適なプレイを実現できないゲームとして比較的広く知られています(関連用語:慣性移動)。

メモリ検索(Memory Search, aka. Cheat Search)

Memory Watchの項で述べたとおり、目的の数値が格納された変数のアドレス(場所)を探す機能です。

Memory Searchはメモリ領域の個々の内容に対して値の比較を繰り返すことで、候補を絞り込んで目的のアドレスを見つけます。具体例を挙げましょう。ある敵の体力が格納されているアドレスを知りたい場合を例に、検索候補の絞り込みの概念を示します。

  1. 目的の敵に遭遇します。同時に「検索開始(検索結果をリセット)」します。
  2. 敵を攻撃してダメージを与えます。敵の体力は最初よりは減っているはずですので、「最初の値よりも現在の値が少ない」変数のみに候補を絞り込みます。
  3. さらに敵を攻撃してダメージを与えます。敵の体力はさっきよりも減っているはずですので、「前回検索時の値よりも現在の値が少ない」変数のみに候補を絞り込みます。
  4. さらに攻撃したら敵が倒れました。マイナスになっていなければ体力は0のはずですので、「値が0」の変数のみに候補を絞り込みます。

こうした絞り込みを繰り返して目的のアドレスを探します。Memory Searchの形はエミュレータによって多少異なりますが、基本的な概念は皆同じです*6

Cheat Searchという別名が示すとおり、この機能は改造コードの検索に用いられます。改造コードの中には特殊な形式のものもありますが、基本的には「書き換え対象のアドレス」と「書き込む値」からなる形式であることがほとんどです。そのため、改造コードの情報を集めることで、有用なメモリアドレスを知ることができることがあります。

改造コード(Cheats, RAM hacking)

通常、TAS動画はゲームの改造はしないという規則のものに作られるものなので、改造コードはTAS動画に使ってはいけないものです。しかし、制作前の調査段階では有用な機能として活用することができます。

メモリの値を任意の値へと強制的に変更することで、体力やアイテムが減らないようにしたり、キャラを無敵状態にしたり、通常あり得ない速度で移動させたりすることができます。調査用にゲームを一通りクリアした状態のセーブデータがほしいときには、こういった機能を積極的に活用すると効率的です。

改造コードの情報を集めることは、メモリアドレスの情報を集めることとほぼ同義です。これに関しては上記Memory Searchの項に記してあります。

メモリビューア(Memory Viewer, Hex Viewer)

メモリ内容の閲覧(・書換)をおこなう機能です。一般的なバイナリエディタ(hex editor)の形をしていて、より広い範囲を見渡すのに向いている点がMemory Watchと異なります。16進表示される形に注目して、Hex Viewerと呼ぶ方が多いかもしれません。

そのほかよく使う機能

まだまだかゆいところに手が届く機能がいろいろ!

入力キー表示(Input Display)、フレームカウンタ(Frame Counter)、ラグカウンタ(Lag Counter)

それぞれ異なった機能ですが、情報表示系ということでまとめて紹介します。いずれも重要な機能ですが、ラグカウンタは比較的最近登場した機能です。

Input Displayは、その名のとおりコントローラの入力を画面に表示する機能です(スクリーンショット左下)。自分が入力した内容の確認にも使えますし、他の人の動画を入力とあわせて観賞する目的にも使えます。押されたボタンを文字で表示するもの、コントローラ型の図を表示してくれるものがあります。この表示を利用して文字などを表示させる、input animationに利用されることがしばしばあります。JXQさんのスーパーメトロイド100%Mr.さんのスーパーマリオワールドany%はその代表例です。

フレームカウンタ(frame counter)は、動画の再生状況をフレーム単位で表示する機能です*7スクリーンショット左上、上段)。ある地点までの経過時間を知るのに用いたり、ある動作にかかるフレーム数を計測したりするのに用います。

ラグカウンタ(lag counter)は、ラグフレーム数の合計を表示する機能です(スクリーンショット左上、下段)。ラグ(処理落ち)がいつ、どの程度起きたのかを把握することが容易になるので、それらを積極的に除去したいときに役立ちます。

ラグ(処理落ち)とは、処理量が多すぎるために本来1フレームでおこなわれる処理が1フレーム以内に完結せず、動作速度の低下となって表れる現象です。TASはより早くゲームを終えることを目標としているのですから、ラグは当然邪魔な存在となります。

正確に言えば、ラグカウンタが検知するのは入力を受け付けないことが確実なフレームです。ゲームのプログラムは通常、ハードウェアレジスタと呼ばれるような領域にアクセスしてコントローラからの入力を知り、それに応じて処理をします。ラグカウンタが「ラグ」としてカウントするのは、このような入力処理がおこなわれなかったフレームです。それゆえ、ロード処理やデモシーンもカウントの対象になりえますし、フレームごとの割り込みの中で入力をおこなっているようなゲームでは、ラグカウンタは理想どおりには動いてくれません(ラグカウンタが反応しない例: ロックマンX)。

Autohold, Autofire

AutoholdAutofire特定のキーを押しっぱなし*8、あるいは連射しっぱなしにする機能です。適当な日本語を与えるなら自動押下自動連射といった名前になるのでしょうか。

Aボタンを連射状態に切り替えるキー、Bボタンを連射状態に切り替えるキー……と、ボタンごとに切り替えキーを割り当てできるエミュレータもありますが、どちらかと言えばAutohold用キー、Autofire用キー、解除用キーの3つを用いる形が一般的かと思われます[要出典]。Autoholdキーを押しながら押しっぱなしにしたいキーを押すことで押しっぱなし状態を設定、同様の操作を繰り返すことで状態を解除、Autofireも同様の方法で設定、解除キーでそれらの状態をすべて解除……という具合です。

Autofireを用いると、キーボードの同時押し制約を気にしなくて済みますし、多くのボタンを同時に押すために複雑に指を置く必要もなくなります。その応用として、一人のプレイヤーが複数のコントローラの入力をおこなえば、擬似的な多人数プレイ動画を作ることができます

バイナリ編集(Hex editing) / ムービーエディタ(Movie editor)

この項はエミュレータの持つ機能の話からは少し逸れますが、一機能として捉えてよいような手法かと思うので、ここで説明します。

Hex editing(バイナリ編集)*9とは、動画ファイルをStirlingなどのバイナリエディタで開いて編集することで、記録されているキー入力情報を部分的に編集する手法のことです。主にはわずかにキーのタイミングをずらすことでエミュレータの不具合からなる記録ずれ(desync)を直したり、他の動画の一部内容を移植(コピペ)したりする目的で利用されます。ファイルを直接数値レベルで編集するため、hex editingにはTASVideos / Emulator Resources / Formatsにあるようなファイル構造の知識が必要です。

Hex editingはファイル構造の知識を必要とする点、操作を間違えたときに動画を破壊してしまう点などから、実践にいくらか難があります。そのため最近では、こうした入力の編集をおこなうための専用のエディタが存在します。TAS Movie Editorスクリーンショット)が代表的ですが、他にもいくつか同種のエディタが存在します。また、最近リリースされたFCEUXは、TASEditという名のエディタを内部に持っています(スクリーンショット)。今後は外部エディタに限らず、こういった内部エディタも実装されていくのかもしれません。

スクリーンショットのとおり、フレームカウントと各ボタンを見出しにした表形式のインタフェースが主流ですが、個人的にはまだ理想の形を追求できるのではないかと思っています。わたしは過去にMIDIシーケンサのようなピアノロール式の内蔵エディタを提案しました(画像編集による仮想スクリーンショット)。なにかしらの画期的な案をお持ちの方、ぜひあなたの案をお聞かせください。

デバッガ(Debugger)

エミュレータやROMのバグ(不具合)を発見・修正するための手助けをおこなう機能ですが、TAS動画制作のための調査にももちろん役立ちます。

デバッガという言葉がどのような機能を指すかはやや不明瞭ですが、ROMのアセンブル(disassemble)機能、特定の処理でエミュレータの実行を一時停止させることができるブレークポイント(breakpoint)機能、プログラムの実行経過を逐一出力するトレースログ(trace logger)機能などが代表的なのではないでしょうか。

なにを言っているのかよくわからないという方が多いかとも思いますが、デバッガはこういう言葉を聞いてなんとなく意味がわかる、プログラミングやゲーム機の仕様に精通した人のためのものです。そのため、他の機能に比べると広く一般に利用されているとは言い難いです。しかし、とても強力なツールです。

その他の実装が望ましい機能

少しTAS制作の本流からは外れるものをリストアップしておきます。

  • AVIファイル出力(Export to AVI)
  • ショートカットキー編集(Key remapping)
  • グラフィックレイヤーの表示・非表示切り替え

マイナーな機能

またの名を「gochaが使っていない機能」。あまり多くのエミュレータに実装されていない機能や、聞いたことがあるけれど見たことがない機能などをまとめます。

キーマクロ・入力プリセット

特定のパターン入力を簡単におこなうための機能です。少なくともSnes9xにはわたしが実装したlazymacroと呼ばれるマクロがあります。ほか少数のエミュレータも似たような機能を持ってはいるようです。設定、使い方がわかりませんが…… (;・ヮ・)

たとえばスーパーマリオワールドには「方向キーを5フレーム間押しっぱなしにした後、6フレーム間離す」という操作を繰り返す6/5と呼ばれる走法がありますが、このような操作を手動でおこなおうと思うと、キーを押したフレーム数を自ら数えなければならず、非常に手間がかかります。lazymacroはこれを解決するために書かれました(本当)。

巻き戻し(Rewind)

Fast forwardの項で述べたとおり、仕組み上、途中でステートを記録していない限り、キームービーを特定の箇所までシークするには先頭から当該箇所までの再生をおこなわなければなりません。これゆえ、ステートなしで動画を即時に巻き戻すのは基本的に不可能です。それならば、一定時間ごとにステートを記録して巻き戻しを可能にしようという発想がRewindという機能です。

Rewind機能を有効にすると、一定時間ごとに自動でステートが記録されます。記録間隔とスロット数はユーザ側で設定します。密にステートを記録するほど詳細な巻き戻しが可能になりますが、ディスク等のリソースなど消費コストが高くなるばかりなので、あまりおすすめできません。

便利そうに思わなくもないのですが、手動に慣れているので使っていません。VisualBoyAdvanceに実装されている機能です。

Frame Search

「何度もステートをロードしながら、1フレームずつ入力(を離す)タイミングをずらす試行を繰り返す」という手順を簡略化する機能がFrame Searchであるようです。試した限りでは、VisualBoyAdvanceにおける使い方は次のような手順のようです。

  • まずは押しっぱなしにしたいキーを押した状態で「Frame Search」で検索を開始します(frame advanceを交えておこないましょう)。するとポーズが解除されてゲームが動きます。
  • ボタンを押している時間をさらに長くしたい場合は再度「Frame Search」を実行すると、もう1フレームボタンを押さえる時間が長くなった状態で、先ほどと同様にゲームが動きます。
  • 同じ要領でタイミングをずらしていくことができます。「Frame Search Prev」は進めたタイミングを戻すのに使うことができます。
  • 満足行く結果を出してくれる箇所が見つかったところで「Frame Search End」にて終了。ボタンを押さえたあとの状態がロードされ、エミュレータはポーズ状態になります。

とまあ、いまいち用途が狭いようなよくわからない機能です。完全に実装しているエミュレータはVisualBoyAdvanceしかないこともあって、使っていません。

ステートの「元に戻す・やり直し」(Savestate Undo)

上書きしてしまったステートを読み込む機能です。上書きされるステートをエミュレータが自動的にバックアップすることで実現されます。最近になってFCEUXがこの機能を実装したという噂です。

ステートビューア(Savestate Viewer)

フォーラムでこのような機能の要望を耳にしたような覚えがあるだけで、実在の機能を見たことがありません。おそらく現存しません。

保持しているステートの閲覧・入出力を効率的におこなう補助をしてくれるものと思われます。実在する機能がないのでどのような図を思い描いていいのか悩むところですが、個人的にはビジュアルノベルのセーブ選択画面のように、スクリーンショットのサムネイルや時間などの情報を表示したウィンドウのようなものを想定しています。その形が正解だとすれば、ZSNESのステート一覧表示はそれを実現したものと言えなくもないでしょう。

savestate treeという言葉もどこかで聞いた覚えがあります。上書きされたステートを含めた履歴のツリーを提供する機能でしょうか。ビューアとの関連も深いと思われる話です。

Picture comparator(画像の比較)

これもアイデア止まりと思われる機能です。2枚の画像を比較するだけの機能です。並べて表示したり、重ねて表示したり、類似度計算したり?

Luaスクリプト(Lua scripting, EmuLua)

最近急激に発展を遂げている、TAS第三世代の必須機能とも言える代物です(KO・U・FU・N☆)。TAS以外への応用も広く考えられる、夢のある機能だと思います。

Luaとは

Luaプログラミング言語です。「汎用性が高い」「動作が高速」「比較的容易に実装が可能で、移植性に優れている」といった特徴から、特定のソフトウェアの組み込む用途でよく用いられます。オンラインゲームが好きな人の中には、ひょっとするとなじみのある人もいるかもしれません。

for i = 1, 9 do
  for j = 1, 9 do
    io.write(string.format("%2d ", i * j))
  end
  io.write("\n") -- new line
end

上のプログラムは九九の計算表を出力するLuaソースコードです。言語の雰囲気をつかむ参考として記してみました。Luaという言語が単体でおこなえることは、上記のような簡単な入出力、C言語の教本に出てくるような単純な処理に過ぎません。しかし、モジュール(プラグイン)によって機能を拡張したり、ホスト(スクリプトの実行主、ここではエミュレータのこと)から提供される機能を組み合わせたりすることで、その可能性は限りなく広がります。

EmuLua

近年、TAS用のエミュレータにはこのLuaスクリプトを実行する機能が整備されてきています。エミュレータ上で動くLuaなので、EmuLuaと呼ばれたりしています。ここでもEmuLuaの通称で呼ぶことにします。

EmuLuaではLuaの基本構文・ライブラリに加えて、エミュレータ側がいくらかの関数を提供します。これにより、エミュレータの状態を取得したり、エミュレータの動作を制御したりすることができます。たとえばどんなことができるのか、Gens Luaの仕様を元に簡単に羅列してみましょう。

  • メモリの読み書き
  • ステートの読み書き
  • ゲーム画面の上に好きな絵を描ける(半透明の重ね合わせも可能)
  • 動画の再生・記録の開始・停止。速度変更などの動作制御
  • コントローラ入力、フレームカウンタ、ラグカウンタ、動画を読み書きしているかなど、各種状態取得
  • キーボード入力、マウス座標などユーザ入力の取得
  • ファイル入出力、GUIウィンドウ表示 ※EmuLuaの機能ではないですが紹介。前者はLuaの基本ライブラリで、後者はiup等のモジュール拡張で可能です。
  • 各種処理はいくつかの特定の操作時・タイミングにあわせておこなえる(フレームエミュレーション直前、フレームエミュレーション直後、画面描画直前、ステート入出力時、特定メモリアドレスの読み・書き・実行時など)

これらの機能を組み合わせることで、ユーザは自ら新しい機能を作り出すことができます。また、特定ゲーム向けに動作するbot試行スクリプト、画面に各種ステータスを追加表示するスクリプト、大胆に新たな遊びを開発してしまうスクリプトなど、発想次第で非常にいろいろなことが可能になります。

実装の現状

Luaスクリプト機能は多くのエミュレータで整備途上の段階にあります。上に記したような機能のうち、一部しか持たなかったり、実装が不完全だったりすることがまだまだありますし、今後の仕様変更がないとも言い切れません。でも、使ってみると楽しい機能です。

実装・ドキュメントともに整備されているのがGens rerecordingです。他のエミュレータにおけるスクリプト機能実装の礎にもなっているので、これには一度目を通してみることをおすすめします。

次いで、FCEUXは高度なサンプルスクリプトが充実していますし、リファレンスも付属しています。こちらも遊びながらEmuLuaの可能性を感じられるので、一度動かしてみることをおすすめします。

その他、Snes9x、VisualBoyAdvance、DeSmuME、PCEJin、VBjinなどにスクリプト機能がありますが、実装状況はまちまちで、ドキュメントもあまり整備されていません。スクリプトを書くにあたっては、Gensのリファレンスを参考したり、ソースコードlua-engine.cpp)から実装状況を読んだりしながら手探りで行うことになるかと思います。

Linux版はWindows版に比べると、Luaスクリプト機能のサポート状況が劣るかもしれません(メンテする人がいなくてLinux版自体放置状態になっていることも珍しくありません)。WineでWindows版を使うのが一番確実なように思います。

入門の扉

EmuLuaに手を出す以前に、スタンドアロンLuaをインストールして、まずはLuaという言語に関して学ぶことを個人的にはおすすめします。Lua公式ページほか、いくらかの解説サイトをあたれば、インストールに困難を感じることはまずないでしょう。

リファレンスマニュアルは学習を目的として読むにはあまり向かないので、入門向けの解説サイトを探して読むとよいでしょう。わたしはKaretta|Luaプログラミング入門でひととおりの言語の雰囲気をつかみました。

EmuLuaの整備状況は上で述べたとおりです。Snes9xとVisualBoyAdvanceは今はまだLuaスクリプト機能を「リリース」していないため、残念ながら現状を記したドキュメントやサンプルに乏しいです(実装状況を知るにはソースコード lua-engine.cpp に直接目を通してもらうほかありません><)。FCEUXやGensはその点がある程度整備されているので、Snes9xやVBALuaスクリプトを書こうとする場合にも、GensやFCEUXのマニュアルを参照してみるとよいでしょう。

書きたいものが決まっている人は、リファレンスとサンプルをあたりながら実現に向かってがんばってください! 使ってみたいけどとくに書きたいものはないという人に関しては、とりあえずは「追加情報表示」などが手出ししやすくておすすめです。

EmuLuaの書き方に関する入門Tipsや新しい利用案などは、経験と実装が整ったところでそのうち書いてみたいと思っています。その一方、誰かが斬新なドキュメントやサンプルを出してくれることにも期待しています (o>ヮ<)o

サンプル -映像で見るEmuLuaの世界-

YouTubeに先人たちの素晴らしいスクリプトの動作例があるので紹介します。これらのソースはFCEUXのサンプルに含まれています。XKeeperさんとmiauさんのスクリプトの楽しさにはたびたび驚かされています。

もうひとつ、最近書かれたものなのでサンプルには含まれていませんが、EmuLuaでテトリスの通信対戦を実現している驚きの動画。

以下、わたしが書いた半端なSnes9x用スクリプトの動画もついでに掲載。まずは初スクリプト、SMWのデバッグパッチの再現+α。

続いてはマウスカーソルでグラディウスを動かすだけの簡単なお仕事です。

マウスカーソル操作に絡んでまた他者製スクリプト紹介。WiiハンドルF-Zeroを遊んでいます。よく思いつくものです。

以上、ざっといくつか並べてみました。興味をもった人はいますぐるあるあするのだ! (>ヮ<)/

*1:TASって完成作品以外は視聴者層からは実態がつかみにくいところがあるので、将来的には「TASLaboを訪れればだいたい誤解なく直感的にその世界がわかる」という感じにしてみたいと思っています。

*2:TAS制作者はキーボードとジョイパッドどちらを使うのでしょうか。#TASersで尋ねてみた限りではどちらを使う人もそれなりにいました。ジョイパッドはゲーム特化のデバイスであること、同時押しの制約を受けにくいことが魅力かもしれませんが、キーボードにも多数のキーがあるという利点があります。いずれにしても、どちらかでなければならないということはなく、好みの問題です。ちなみにgochaはノートPCのキーボードを使っています。

*3:セーブデータの不正改変を見抜くことの困難さゆえ、TASでは基本的にはまっさらな状態からゲームを開始します。クリア後に出る隠しキャラを用いた動画を記録したい場合などはセーブデータからゲームを開始しますが、この場合もセーブデータの制作過程が明確であることが求められます。既存のTAS動画から得られるセーブデータを用いるか、あるいはクロノトリガーのつよくてニューゲームTASのように、セーブデータ作成用の動画を書き下ろすのが一般的です。

*4:今どきCMカットもできないのかなんて言わないで! うちのそういう録画できないんだもん! (>д<)

*5:より厳密には、閲覧したいフィールドのサイズ、符号の有無、10進表示・16進表示の選択なども必要です。

*6:個人的には、スクリーンショットにあるGens rerecordingのRAM Searchが、執筆現在で一番優秀なMemory Searchを持っていると感じています。エミュレーションと並行した絞り込みや、値の差を条件とした検索は、他のエミュレータにも取り入れてほしいところです。

*7:TAS動画制作ではフレーム単位で表示させるのが普通ですが、設定によって一般的な時間表記で表示できるエミュレータもあります。また、最近は動画再生時でなくともフレームカウンタを表示させられる形式が一般的になりつつあり、この場合はリセットからの経過時間を表示します

*8:より正確には、押した押してないの情報を反転させるような実装であることが多いです。そうすることで、1フレームだけキーを離すような操作もAutoholdの解除なしにおこなえるようになります。

*9:ファイルをバイナリレベルで編集するためこのように呼ばれています。しかし、編集しやすいようテキストベースで記述されている、FCEUXのムービーファイル(fm2ファイル)のようなものもあるので、必ずしもバイナリエディタを開く必要があるとは限りません。