Github: https://github.com/openai/retro
ジムレトロ
Gym Retroは、Libretro APIを使用してGym環境に変換するビデオゲームエミュレータコアのラッパーです。 これはいくつかの古典的なゲームコンソールと異なるゲームのデータセットをサポートしています。 Linux、macOS、WindowsでPython 3.5、3.6、3.7をサポートしています。
各ゲームには、ゲーム内変数のメモリ位置、それらの変数に基づく報酬関数、エピソード終了条件、レベルの始めのsavestate、およびこれらのファイルで動作するROMのハッシュを含むファイルが格納されたファイルがあります。 ROMは含まれておらず、あなた自身で入手しなければならないことに注意してください。 ほとんどのROMハッシュは、それぞれのNo-Intro SHA-1合計から供給されます。
サポートされるシステム:
- アタリ
- Atari2600(ステラ経由)
- NEC
- TurboGrafx-16 / PCエンジン(Mednafen / Beetle PCE Fast経由)
- 任天堂
- ゲームボーイ/ゲームボーイカラー(ガンバット経由)
- ゲームボーイアドバンス(mGBA経由)
- 任天堂エンターテインメントシステム(FCEUmm経由)
- スーパーニンテンドーエンタテインメントシステム(Snes9x経由)
- セガ
- GameGear(Genesis Plus GX経由)
- ジェネシス/メガドライブ(Genesis Plus GX経由)
- マスターシステム(Genesis Plus GX経由)
個々のコアのライセンスについては、 LICENSES.mdを参照してください。
インストール
ジムRetroにはPython 3.5または3.6が必要です。 あらかじめお使いのOSに適したディストリビューションをインストールしてください。 一部のコアとの互換性の問題により、32ビットオペレーティングシステムはサポートされていませんのでご注意ください。
余分な前提条件
建物のジムレトロでは、少なくともgcc 5またはclang 3.4のいずれかが必要です。
あなたがmacOS上にいる場合は、10.11以上が必要です。 また、LuaJITはmacOS上で正しく動作しないので、まずhomebrewからLua 5.1をインストールする必要があります:
brew install pkg-config lua@5.1
バイナリからインストールする
pip3 install gym-retro
ソースからインストールする
ジムレトロを構築するには、まずCMakeをインストールする必要があります。 パッケージマネージャ、 公式サイトからダウンロード、 pip3 install cmake
いずれかを使ってこれを行うことができます。 Windowsで公式インストーラを使用している場合は、CMakeにシステムPATHに自身を追加するように指示してください。
Windowsの前提条件
Windowsでない場合は、次のセクションに進んでください。 それ以外の場合は、 GitとMSYS2 x86_64もダウンロードしてインストールする必要があります。 gitをインストールするときは、WindowsのコマンドプロンプトからGitを使用するように選択します。
msys2をインストールしたら、MSYS2 MinGW 64ビットプロンプトを開き(スタート> MSYS2 64ビット)、以下のコマンドを実行します:
pacman -Sy make mingw-w64-x86_64-gcc
完了したら、プロンプトを閉じてGit CMDプロンプトを開き(Start> Git)、これらのコマンドを実行します。 MSYS2を別のディレクトリにインストールした場合は、comamndのC:\ msys64の代わりにそのディレクトリを使用してください。
path %PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
set MSYSTEM=MINGW64
その後、同じプロンプトで、まずそれを閉じることなく、次のセクションの手順に進みます。 プロンプトを閉じると、最後のコマンドを再実行してから再構築する必要があります。
建物
git clone --recursive https://github.com/openai/retro.git gym-retro
cd gym-retro
pip3 install -e .
サブモジュールの更新
git pull
実行すると、サブモジュールが更新されることがあります。 通常、これは自動的に処理する必要がありますが、エラーが発生した場合は、再構築する前に次の手順を実行することでこれを迅速に修正できます。
git submodule deinit -f --all
rm -rf .git/modules
git submodule update --init
ジムで使う
import retro
env = retro.make(game='SonicTheHedgehog-Genesis', state='GreenHillZone.Act1')
統合ユーザーインターフェイス
インテグレーションUIを使用すると、変数を簡単に見つけ出し、報酬関数で何が起こっているのかを簡単に確認できます。
バイナリからインストールする
バイナリはすぐに来るだろう
ソースからインストールする
マックOS
brew install pkg-config capnp lua@5.1 qt5
cmake . -DCMAKE_PREFIX_PATH=/usr/local/opt/qt -DBUILD_UI=ON -UPYLIB_DIRECTORY
make -j$(sysctl hw.ncpu | cut -d: -f2)
open "Gym Retro Integration.app"
Linux
sudo apt-get install capnproto libcapnp-dev libqt5opengl5-dev qtbase5-dev
cmake . -DBUILD_UI=ON -UPYLIB_DIRECTORY
make -j$(grep -c ^processor /proc/cpuinfo)
./gym-retro-integration
Windows
Windows上のソースからビルドすることは、現在構成が難しいです。 クロスコンパイル用のDockerコンテナは、 openai / travis-buildで入手できます。
ファイルを再生する
UIを使用してリプレイファイルを作成して表示することができます(ゲーム>ムービー再生…)。 スクリプト内の再生ファイルを管理する場合は、次のようになります。
記録
import retro
env = retro.make(game='SonicTheHedgehog-Genesis', state='GreenHillZone.Act1', record='.')
env.reset()
while True:
_obs, _rew, done, _info = env.step(env.action_space.sample())
if done:
break
再生
import retro
movie = retro.Movie('SonicTheHedgehog-Genesis-GreenHillZone.Act1-0000.bk2')
movie.step()
env = retro.make(game=movie.get_game(), None, use_restricted_actions=retro.ACTIONS_ALL)
env.initial_state = movie.get_state()
env.reset()
while movie.step():
keys = []
for i in range(env.NUM_BUTTONS):
keys.append(movie.get_key(i))
_obs, _rew, _done, _info = env.step(keys)
ビデオにレンダリングする
python scripts/playback_movie.py SonicTheHedgehog-Genesis-GreenHillZone.Act1-0000.bk2
環境
どのような環境がありますか?
import retro
retro.data.list_games()
どのような初期状態がありますか?
import retro
for game in retro.data.list_games():
print(game, retro.data.list_states(game))
変更ログ
スクリプト例
examples
ディレクトリにはスクリプト例があります。
-
random_agent.py
は、指定されたゲームと状態ファイルをロードし、毎回ランダムなアクションを選択します。 現在の報酬が印刷され、シナリオが完了すると終了します。 そのゲームに報酬またはシナリオデータが定義されていない場合、例外がスローされます。 このスクリプトは、シナリオが適切に設定されているか、報酬関数があまりにも寛大でないかを確認するのに便利です。
新しいROMを追加する
- 米国
(USA)
、(USA, Europe)
、(Japan, USA)
などで表されるROMの米国版が好ましい -
sorted
フォルダ内のROMは良好なバージョンのROMであることが確認され、reject
フォルダ内のROMよりも優先されます。 -
unsorted
フォルダは、sorted
フォルダまたはreject
フォルダに自動的にソートされるROMの生のリストであるため、無視する必要があります。 - ROMに
.bin
拡張子が付いている場合は、そのシステムの正しい拡張子を持つように名前を変更します 。 - Gym Retro Integrationアプリケーションを使用し、[ファイル]メニューの[統合]オプションを選択して統合を開始します。
ファイル形式
いくつかの異なるファイル形式が使用されています。
ROM
ROMファイルにはゲーム自体が含まれています。 各システムには、特定のROMが実行されているシステムを示す固有のファイル拡張子があります。
-
.md
:Sega Genesis(メガドライブとも呼ばれます) -
.sfc
:Super Nintendo Entertainment System(スーパーファミノムとも呼ばれます) -
.nes
:任天堂エンターテインメントシステム(別名ファミコン) -
.a26
:Atari 2600 -
.gb
:任天堂ゲームボーイ -
.gba
:任天堂ゲームボーイアドバンス -
.gbc
:任天堂ゲームボーイカラー -
.gg
:セガゲームギア -
.pce
:NEC TurboGrafx-16(PCエンジンとも呼ばれます) -
.sms
:セガマスターシステム
これらのシステムのROMは、異なる拡張子を使用することもあります。たとえば、Genesisでは.bin
、Atariでは.bin
などです。これらの場合、前述の拡張子を使用するようにROMの名前を変更してください。
retro.import
を使用してROMをインポートできます。
python3 -m retro.import /path/to/your/ROMs/directory/
Gym Retroにはテスト目的で以下の非商用ROMが含まれています:
- Anthroxの128サインドット
- Sega Tweenベン・ライヴス
- ハッピー10! ブラインドIO
- Chris Covell 著512色テストデモ
- Dekadrive by Dekadence
- Derek LedbetterによるAutomaton
- doxによる火災
- dr88によるFamiCONイントロ
- ElectrokinesisによるAirstriker
- ヴァンテージで失われた大理石
州
エミュレーションにより、ビデオゲームシステムの全状態をディスクに保存して復元することができます。 これらのファイルはエミュレータに固有ですが、常に.state
で.state
ます。 これらはスタンドアロンバージョンのエミュレータで使用されているものと同じですが、gzipされています。
ゲーム情報マニフェスト( data.json
)
ゲームの内部動作に関する情報は、ROMの横にdata.json
というファイルに格納されます。 このJSONファイルには、メモリに関する変数の場所やフォーマットなど、ゲームに関する「真実の真実」の情報が記録されています。 これらのマニフェストは、現在セクションが1つだけ定義されていますが、セクションに分かれています。
info
セクション
マニフェストのinfo
セクションには、ゲーム変数のメモリアドレスがリストされます。 info
セクションの各エントリは、メモリアドレスと次の値を指定するキーで構成されます。
-
address
:変数の最初のバイトのRAM配列へのアドレス。 -
type
:この変数の型記述子。 この値の形式については、上記補遺を参照してください。
次のマニフェストでは、符号なしビッグエンディアン形式で4バイト幅の128バイトに位置する1つの変数score
を持つゲームの例を示します。
{
"info": {
"score": {
"address": 128,
"type": ">u4"
}
}
}
補遺:タイプ
タイプは3つの部分で構成されています。
- エンディアン
- フォーマット
- バイト
エンディアンは、メモリ内のバイトの順序を参照します。 たとえば、16進数の文字列0x01020304
を使用します。これはさまざまな方法で格納できます。
- ビッグエンディアン:
0x01 0x02 0x03 0x04
- リトルエンディアン:
0x04 0x03 0x02 0x01
- 中位のエンディアン(大きな外側/少し内側):
0x02 0x01 0x04 0x03
- ミドル・エンディアン(内外):
0x03 0x04 0x01 0x02
以下の記号はエンディアンに対応しています:
-
<
:Little -
>
:ビッグ -
><
:中(大/小) -
<>
:中(小/大) -
=
:ネイティブ(ほとんどのコンピュータではほとんど) -
>=
:中(大/ネイティブ) -
<=
:中(少し/ネイティブ) -
|
:Do not care(シングルバイト値の場合のみ有効)
注 :ミドル・エンディアンは非常にまれですが、ビッグ・エンディアンの順序で2つの16ビット値としてネイティブ・エンディアンと32ビット値の16ビット値を格納するシステムもあります。 このような例の1つは、エミュレータのGenesis Plus GXです。 したがって、ビッグエンディアンシステムでは、リトルエンディアンシステムで>=u4
と表示される場合、フォーマットは=u4
(aka >u4
)と表示されます。 そのようなデータには手作業による手入れが必要な場合があります。
フォーマットとは、メモリ内の値がどのように格納されるかを指します。 たとえば、16進バイト0x81
ます。 それは10進数で3つのことを意味することができます:
- 署名なし:129
- 署名:-127
- バイナリコード10進数:81
- 低ニブル2進コード10進数:1 NB:ニブル
0xA
–0xF
は2進化10進数では使用できません。
次の文字はフォーマットに対応しています:
-
i
署名しました -
u
:署名なし -
d
:バイナリコード10進数 -
n
:低ニブルのバイナリコード10進数
最後の部分は、メモリ内で値が占めるバイト数を示します。 理想的には、これは2、例えば1,2,4,8などの累乗でなければなりませんが、いくつかのゲームでは2つの値の非累乗が使用されます(例えばSuper Mario Bros.のスコアは6バイトです)。 2つの変数の非累乗がサポートされています。
NB :ネイティブエンディアンとミドルエンディアンは、4バイト未満の2つのサイズまたはサイズの非出力では機能しません。 現在、4バイトのミドル・エンディアンのみが適切にサポートされています。
いくつかの例を次に示します。
-
<u2
:リトルエンディアンの2バイトの符号なし値(すなわち、0x0102
– >0x02 0x01
) -
<>u4
:ミドル・エンディアン(小/大)4バイトの符号なし値(つまり、0x01020304
– >0x03 0x04 0x01 0x02
) -
>d2
:ビッグエンディアンの2バイトのバイナリコード10進数値(つまり、1234
– >0x12 0x34
) -
|u1
:シングル・シングル・バイト -
<u3
:2バイトの非出力(すなわち、0x010203
– >0x03 0x02 0x1
) - = n2:ネイティブエンディアンの2バイト低ニブル2進化10進値(Intelおよび大部分のARM CPUでは
12
– >0x01 0x02
、PowerPC CPUでは0x02 0x01
)
いくつかの非例:
-
|i2
:有効だが推奨されない:2つの符号付きバイト、未定義の順序 -
<u1
:有効であるが推奨されない:1バイトに順序がない -
?u4
:無効:定義されていないエンディアン -
>q2
:無効:未定義フォーマット -
=i0
:無効:ゼロバイト -
><u3
:無効:2つの中間エンディアンバイトの非出力 -
<=u2
:無効:中間のエンディアンは2つのバイト値に意味をなさない
シナリオ情報( scenario.json
)
報酬関数と完了条件に関する情報は、 retro.RetroEnv
関数を手動でオーバーライドするか、シナリオファイルを記述することで指定できます。 シナリオファイルには、情報マニフェストで定義された変数から報酬関数と完了条件を計算するために使用される情報が含まれています。 シナリオファイルで指定された各変数には、正の場合はreward
値が、負の場合はpenalty
値が乗算され、合計されてそのステップの報酬が作成されます。 同様に、これらの変数の状態をチェックして、ゲームが終了したかどうかを調べることができます。 デフォルトでは、シナリオファイルはscenario.jsonからロードされscenario.json
が、代わりのシナリオファイルはretro.RetroEnv
コンストラクタで指定できます。
シナリオファイルはJSONで、次のセクションで指定します。
reward
セクション
報酬関数の計算に使用した報酬セクションは、次のサブセクションに分かれています。
variables
サブセクション
variables
サブセクションは、現在のメモリ状態から報酬関数を計算する方法を定義するために使用されます。 variables
セクションの各変数について、値が計算され、係数が掛けられ、次にこのステップの報酬関数に追加されます。 値がどのように抽出されるかは、 op
/ measurement
/ reference
値によって指定されます(これらのオペレーションの意味については以下の補遺を参照してください)。 デフォルトのmeasurement
はdelta
です。 デフォルトのop
はありません。デフォルトでは、値はrawに渡されます。
-
reward
:値が正のときに値を掛けた係数。 -
penalty
:値が負の場合に係数を掛けた値。
注意 :マイナスのpenalty
は、係数で乗算される値が負であるため、減算ではなく報酬関数に加算を加えることを意味します。
time
サブセクション
time
サブセクションは、いくつのステップを取ったかに基づいて報酬を作成するために使用されます。 2つの値を指定できます。
-
reward
:1ステップごとに報酬関数に加算される値。 -
penalty
:毎回報酬関数から減算される値。
done
セクション
done
セクションは、ゲームの終了に達したかどうかを計算するために使用されます。 最上位レベルでは、次のプロパティを使用できます。
-
condition
:done
条件をどのように組み合わせるかを指定します。-
any
:done
セクションのany
の条件が満たされます。 これがデフォルトです。 -
all
:done
セクションのすべての条件が満たされます。
-
現在、以下のサブセクションがあります。
variables
サブセクション
variables
サブセクションは、現在のメモリ状態から完了条件を計算する方法を指定します。 variables
サブセクションの各変数は、演算/ measurement
/ reference
値ごとに抽出されます(これらの意味については、以下の操作の補遺を参照してください)。 デフォルトのmeasurement
はabsolute
measurement
です。 デフォルトのop
はありません。デフォルトでは、値は無視されます。
補遺:操作
ゲームは、さまざまな方法で情報をメモリに格納することができます。そのため、必要な特定の情報もさまざまな形で表現できます。 基本的な前提は、生の値がメモリから抽出されると、操作を定義して有用な形式に変換できることです。 さらに、与えられたステップの生の値や、2つのステップの間のデルタが必要な場合があります。 したがって、3つの特性が定義される。
-
measurement
:生の値を抽出するために使用される方法。 現在の値に対してはabsolute
であり、現在の値と以前の値との差に対してはdelta
であってもよい。 デフォルトはコンテキストによって異なります。 -
op
:この値に適用する特定の操作。 有効な操作は以下で定義されています。 -
reference
:必要に応じて操作の参照値。
次の操作が定義されています。
-
nonzero
場合:値が0の場合は0、それ以外の場合は1を返します。 -
zero
:値が0の場合は1を返し、それ以外の場合は0を返します。 -
positive
:値が正の場合は1を返し、それ以外の場合は0を返します。 -
negative
:値が負の場合は1を返し、それ以外の場合は0を返します。 -
sign
:値が正の場合は1を、負の場合は-1を返し、そうでない場合は0を返します。 -
equal
:値がreference
値と等しい場合は1を返し、そうでない場合は0を返します。 -
not-equal
:値がreference
値と等しくない場合は1を返し、そうでない場合は0を返します。 -
less-than
:値がreference
値より小さい場合は1を返し、そうでない場合は0を返します。 -
greater-than
:値がreference
値より大きい場合は1を返し、そうでない場合は0を返します。 -
less-or-equal
:値がreference
値以下の場合は1を返し、それ以外の場合は0を返します。 -
greater-or-equal
:値がreference
値以上の場合は1を返し、それ以外の場合は0を返します。