PICO PARK:Classic EditionでRemote Play Togetherを無理やり遊べるようにした話
タイトルの通りです。PICO PARK:Classic Editionにおけるバグ(仕様?)である、「ゲーム起動後に接続したコントローラーがゲーム内で認識されない」という問題が一向に修正されない(恐らく開発者もこのゲームを見捨てている)ので、自分でこの問題を乗り越えようと戦った結果です。
10人で遊ぶことはまだ試していないですが、とりあえず上手くは行きそう。当然ですが、RPTで遊ぶ場合は全員コントローラーが必須です。
【追記】
作った当初は気がついていなかったですが、キーボードを許可することで予期せずAlt+F4が発動してしまったりするなどのキーコンの問題を確認しました。後ほどそういったことが起こらないような対策を考えるので、それまではそういった問題があることを前提において使ってください。基本的には3Pと9P・10Pが同時にプレイしなければ大丈夫なはずです。
修正したファイルを適用しました。
3Pのキーコンフィグの変更と、vdfファイルの変更を行いました。
Altキーを使用しない設定にしたので、おそらく大丈夫なはずです。
ただし、依然としてキーボードを使用する構成ではあるため、イタズラによってプレイを阻害される可能性があることを留意の上で使用してください。
やり方
この記事を見に来たということは恐らくRPTを楽しみたいと思っている人だと思うのでさっさとやり方を書きます。
今回の記事は「PICO PARK:Classic Edition」という無料版のPICO PARK専用です。有料版の1と2はSteam Inputでの制御が可能になっていますので、この記事を読む必要はまったくありません。
また、このコンフィグファイルで自機色を選択できるのは2P以降です。1Pとしてホストする場合、あなたは水色で固定となります。そのため配布ファイルにも水色用のコンフィグはありません。
その1:PICO PARK内でキーコンフィグを設定する
キーボードのキーを余すことなく使用したキーコンフィグです。1P以外がキーボードで操作するのはほぼ不可能になりますが、このキーコンフィグにコントローラーのボタンを割り当てることで各キャラクターを制御します。
画像と同じように各プレイヤーのキーコンを変更してください。
3Pの「L BRACKET」は、キーボード右上の「{」を押せば設定できます。うまくいかない場合はその1.5を参照。
その1.5:テンキーがない人向け
テンキーが使えない場合、userdata.luaファイルのコピーや、スクリーンキーボードを使うことで突破できます。
ただし、userdata.luaファイルは記録タイムやクリア回数なども保存されているため、上書きするとそのデータまで消えるので注意。ハイスコアを上書きしたくない場合は、luaファイルを直接いじりましょう。逆に言えば今のクリアタイムがどうでもいい人は上書きでもOKです。
書き換えるには、まずゲームのインストールフォルダに行きます。構造的にはSteamLibrary→steamapps→common→PICO_PARK→saveフォルダー内にuserdata.luaがあります。
わからない場合はSteamからローカルファイルを閲覧して開きましょう。Steam上でゲームを選択してから、歯車マーク→管理→ローカルファイルを閲覧 で指定フォルダが開きます。
saveフォルダ内にあるuserdata.luaをメモ帳やコードエディターなどで開きます。
userData=
{
soundVolume=2,
isFullscreen=1,
--padconfig setting
padConfig=
{
{
product=3040521083,
start=7,
a=0,
b=1,
},
{
product=3548955058,
start=7,
a=0,
b=1,
},
{
product=103180431,
start=7,
a=0,
b=1,
},
{
product=1221647035,
start=7,
a=0,
b=1,
},
},
--tecogamepadconfig setting
tecogamepadConfig=
{
start=4,
a=6,
b=7,
},
--keyboardConfig setting
--ここから
keyboardConfig=
{
{
38,
41,
38,
66,
67,
69,
68,
38,
88,
42,
},
{
54,
88,
54,
13,
12,
59,
53,
54,
88,
88,
},
{
61,
88,
61,
63,
62,
60,
86,
61,
88,
88,
},
{
19,
88,
19,
16,
22,
4,
17,
19,
88,
88,
},
{
15,
88,
15,
24,
20,
8,
14,
15,
88,
88,
},
{
6,
88,
6,
0,
18,
3,
5,
6,
88,
88,
},
{
58,
88,
58,
7,
9,
10,
11,
58,
88,
88,
},
{
1,
88,
1,
25,
23,
2,
21,
1,
88,
88,
},
{
47,
88,
47,
43,
44,
45,
46,
47,
88,
88,
},
{
52,
88,
52,
48,
49,
50,
51,
52,
88,
88,
},
},
--ここまで
--stage data
stageData=
{
{
name="stage_push00",
playCount=2,
clearCount=2,
bestTime=
{
4294967295,
4294967295,
21722,
4294967295,
28813,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump00",
playCount=3,
clearCount=3,
bestTime=
{
4294967295,
27138,
54358,
4294967295,
41765,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_majo00",
playCount=3,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
41078,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_weight00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_laser00",
playCount=2,
clearCount=2,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
31678,
254039,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_roulette",
playCount=1,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
61708,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_seesaw00",
playCount=1,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
111616,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_stopwatch00",
playCount=1,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
78346,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_breakout00",
playCount=5,
clearCount=3,
bestTime=
{
4294967295,
217401,
4294967295,
4294967295,
95438,
270742,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_bound00",
playCount=1,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
141511,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_coin00",
playCount=4,
clearCount=2,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
40223,
41998,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_constraint00",
playCount=5,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
143983,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_ghost00",
playCount=2,
clearCount=2,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
183886,
584351,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_multijump00",
playCount=2,
clearCount=2,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
198450,
170577,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_weight01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_majo01",
playCount=3,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump04",
playCount=1,
clearCount=1,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
189528,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_switch_puzzle00",
playCount=4,
clearCount=4,
bestTime=
{
4294967295,
81796,
4294967295,
4294967295,
107336,
217697,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_traffic_light00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_battle00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_pub00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_8bitcafe",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_tetris00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_tetris01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_dr01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_tetrisvs00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_drvs00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_apple00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_physic00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump03",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_multijump01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump07",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_battle00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_breakout01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_stopwatch01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_seesaw01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_invador00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_switch_dr00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_gravity00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_switch_dr_00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_switch_control00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_constraint01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_ghost01",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_tetris03",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_dr00",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_dr02",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_dr03",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_test",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_tetris100",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
{
name="stage_jump02",
playCount=0,
clearCount=0,
bestTime=
{
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
4294967295,
},
},
}
}
セーブデータが必要ない方はこの文面をそのままコピーしてuserdata.luaに貼り付けてください。
スコアを残したい方は、上記に記した「ここから」と「ここまで」と書いてある範囲全体をコピーして、luaファイルの同じところに貼り付けてください。終わったら上の日本語コメントは削除してもOK。
これでキーコンフィグは完了です。
その2:Steam入力用のvdfファイルをDLする
今回作成したキーボード設定をプレイヤー色ごとにコントローラーで利用できるようにしたものです。ここからDLしてください。
十字キーとスティックで移動、ABXYのいずれかでジャンプとなっています。
zipファイルで、中身は自機色に基づく9色分の操作方法が書かれたvdfファイルになっています。DLしたら解凍しておきます。
その3:vdfファイルをインポートする
解凍が終わったら、Steamのコントローラー設定が保存されているフォルダーに行きます。デフォルトではSteam本体のインストール先直下のsteamapps→common→Steam Controller Configs→443864975→configにあるはずです。
ライブラリ用にゲームのインストール先を変えている場合は、必ずしも同じフォルダー内にあるとは限らないので注意です。
Steam本体のインストール先は、デフォルトだとCドライブのProgram Files (x86)のSteamフォルダです。
フォルダーを見つけたら、先ほどのzipファイルを解凍したものをそのままconfigフォルダーへ入れます。この際、zipファイルを解凍したときに2重フォルダーにならないようにしてください。
最終的には、steamapps→common→Steam Controller Configs→443864975→config→461040→.vdfファイル という構造になっていればOKです。
その4:ゲーム内でコンフィグが適用されるかテストする
インポートが完了したらゲームを起動します。この時、テストのためにゲーム起動前はコントローラーを切断しておいてください。
起動したらコントローラーを再び接続します。この状態ではまだ動かせないはずです。
Shift+Tabキーを押して、Steamオーバーレイを開きます。
設定から、スクリーンショットのショートカットキーをF12以外にするか、なくします。(デフォルトのスクショボタンにF12が使われているので、GREENの操作レイアウトと競合させないため)
また、NVIDIAなど、別ソフトのオーバーレイでキーボードショートカットがある場合はそれも全て無効にしておきましょう。Altキーを発動条件にしておけばとりあえず暴発は起こりません。
下のコントローラーアイコンを押します。
Steam入力が有効でない場合は有効にします。「PICO PARK:Classic Edition:ゲームパッドの公式レイアウト」の欄をクリックします。
自分のレイアウト欄に移動します。出てこない場合は、コミュニティレイアウト欄に移動し、Xボタンで「すべてのレイアウトを表示」すると自分のレイアウト欄が出現するはずです。
好きな色を選び、「レイアウトを適用」を押します。Shift+Tabキーでゲームに戻ります。指定した色のキャラクターが動けば導入成功です。念の為、全色でテストすることをオススメします。
もしレイアウトが表示されない場合は、一度Steamを終了してから再度試すと上手くいくかもしれません。
その5:遊び方
導入が完了したら、一度ゲームを落とします。あなたがコントローラーを使用する場合は接続してからゲームを起動します。(1Pのみゲーム内のコントローラー認識で操作するため)
起動したら、オーバーレイの設定からあなたのコントローラーレイアウトをデフォルトのコントローラーに戻します。
戻ってみて、1Pだけが動けばOKです。
その後は、新しく接続されたコントローラーに対してその4に書かれた手順を行うだけです。色が被らないように注意してください。
その6.RPTでの遊び方
通常の方法でRPTを開始します。フレンドを招待するなり、招待リンクを作るなりして全員分の接続を確保してください。
それぞれのコントローラーが確認できたら、その4に書かれている方法と同じやり方で全員にひとつずつレイアウトを適用していきます。
完了したら、RPTに参加している全員にキーボード操作の権限を付与します(プレイヤー名の横にあるキーボードアイコンをクリック)。
ゲームに戻り、全員が操作できれば設定完了です。ゲームを開始して遊びましょう。
おまけ:開発録
ここからは自分語りです。上手くいった場合はこれ以降を読む必要はありません。興味のある方だけどうぞ。
さて、このPICO PARKを知ったのは、実は2年ほど前だったりします。その当時はRPTについて詳しく知らなかったのですが、いとこ達と楽しむぐらいで十分でした。
その後1年経って、RPTを試そうとしたところでコントローラーの問題に気づきました。他のゲームは普通にRPTができるのに、PICO PARKだけはそうもいかなかったです。
色々試して、「コントローラーをゲーム起動前に接続する必要がある」ことまでは突き止めたのですが、それ以降は手詰まりになってしまいました。
諦めてParsecとJoyToKeyを使ったりしましたが、その時は上手く行きました。しかし、Parsecは接続が安定しなかったり、インストールすべきものが多すぎて友達を簡単に誘うのには難があったので、やはりSteam経由で遊べたらベストだなあと思っていました。
RPTではJoyToKeyも機能しなかったし、「先に仮想コントローラーを接続しておき、Steamで繋がったコントローラーの操作を橋渡ししてもらう」ということも考えましたが、その仮想コントローラーを接続する方法が分からずじまいでした。(そもそもデバイス欄にSteam接続のコントローラーがいねえ!!!)
有料版を買うことも考えましたが、ほとんど内容が同じだし、最大人数10人のロマンをみすみす見逃すこともできなかったのです。
その後、Steam上のゲームならなんでもRPTできるようにしてしまう「Remote Play Whatever」というソフトが開発されました。(非Steamゲームとして新しくゲームを追加することでSteamゲーに限らずどんなゲームもRPTできるようにしてしまうスグレモノ)
それを使っていろいろやってみましたが、これも失敗。
諦めてEpicで買ったレイマンレジェンドとかやろうとしてたんですが、ここでも問題が。接続したのに、全然操作できないのです。
というのもこのRPWというソフト、現在プレイ中のゲームを「Spacewar」というよく分からんゲームとしてSteamに誤認させることでRPTを実現しているようで、コントローラー設定が全く上手くいってませんでした。
それもそのはず、Spacewarのデフォルトのコントローラーレイアウトがうんちだったからです。(ジョイスティックの操作が無効になってたり、ボタンにあらぬ操作が割り当てられていたり)
それに気づいてコントローラーレイアウトをいじったところ、うまくいきました。ここでそのレイアウトを編集したりする方法があると学んだワケです。
そんなこんなでまた1年経って、今年のオータムセールでPICO PARK 2を購入しました。もはやClassic Editionで遊ぶことは諦めてたので、2で我慢しようと思ってました。
が、何気なく確認したら、このゲームはコントローラーレイアウトがSteam側で設定できるようになってました。Xboxのボタンとかではなくです。
それを見た時に閃きました。
「コントローラーにキーボード入力を割り当てられたのでは…?」
ということで、すぐさまClassic Editionを起動して設定を始めました。
最終的に、キーボードのキーをふんだんに使ってコントローラーに適用するという力技でRPT用のレイアウトを作りました。
しかし、Xboxコンしか持っていなかったので、Xbox用のレイアウトしか作れませんでした。というわけで、他の種類のコントローラーを持っている人に頼んで、コントローラー設定を進めることに…
Steam入力のメニューも上手く動かず、レイアウト保存したのに保存されてなかったとか、同じレイアウトが重複保存されてたとか、気づいたら2Pと3Pの操作に被りがあったとか、しっちゃかめっちゃかでした。
血反吐吐きながらProコントローラー用の設定中、どうにか楽をする方法はないかと「vdfファイルを他のコントローラーに適用する方法はないものか」とChatGPTに聞いてみたものの、やっぱり的外れの発言しか帰ってこなかった。と思いきや、「Steam入力の汎用設定」という言葉が。
そんなものがSteamに存在しないのは知っていましたが、気になってSteamのコントローラー設定を見たら、「全てのレイアウトを表示」の文字が!!!!!!!
早速Proコンで試したら普通に適用できてしまった。知識不足が仇になった…
なにはともあれ、最終的には上手くいくようになりましたとさ。
受験が終わったら、是非とも10人フルで招待して遊んでみたいものです。
この問題は割と色んな人から嘆かれていたようなので、とりあえずnoteにまとめてみました。
誰かの役に立てますように…
嬉しかったら、ぜひコメントくれよな。