RPGツクール2000におけるマルチコア問題について

  • 2010/08/17(Tue) 加筆・修正
  • 2012/09/30(Sun) 加筆
  • 2014/08/31(Sun) 修正
  • 2015/02/15(Sun) ページ位置の移動

1 : 問題の提起

この問題は簡単に言うと、

マルチコアPC(デュアルコアCPUやクワッドコアCPU)でRPGツクール2000のゲームをプレイすると、
「キー入力の処理」が非常に不安定となり、短時間で入力が連打しているかの様な現象が起きる。

…というものです。

特にキーを押しっぱなしにしたりする必要のある処理(ダッシュなど)では、
処理がガタガタになってしまい非常に不安定になってしまうケースがあります。

RPGツクール2000は発売した時期は古く、今やマルチコアCPUが一般的になっています。
2012年9月に正式に64bitOSに対応するパッチが配信されましたが、この問題は解決されておりません

ツール側の仕様…と言えばそれまでですが、このツールを使っている以上、
これを対処しなければプレイヤーに快適に遊んで貰う事は難しい、と思っています。

現在でも良質なツクール2000ゲーは多く、遊ばれている方々も多いはずです。
この問題によってゲームが上手く動かないのではせっかく作られたゲームも伝わりません。

そこで本記事では、個人的な解釈と手段でこの問題を対策する方法を挙げてみたいと思います。

2 : 問題の対策

まずは実際にゲームを正常に遊べる様にする方法を示します。
大きく分けて2種類の方法があると思われます。

■タスクマネージャからゲームの実行exeに割り当てられているCPUを限定する方法

通常、マルチコアはアプリケーションは各CPUに作業を分けて実行する。(必ずとも作業分割している訳ではない。)
マルチコアで問題が発生するのならば、シングルコアと同様に動作させてしまえば良いという事です。

以下にwindowsXP以降におけるCPU限定方法を示します。

タスクマネージャを起動し、「プロセスタグ」
対象のexe(RPG_RT.EXE)を選択、右クリック
「関係の設定」を選択。
(図1に例を提示)

タスクマネージャ起動後プロセスタグを選択した際の画面
図1:タスクマネージャを起動しプロセスタグを選択した画面

ここでどのCPUでプロセスを実行するか設定できる画面が出るので、
チェックを一つだけにする。
(図2に例を提示)

CPUを一つだけに指定したら、[OK]を押し、設定を適応させる。
これでシングルコアと同様の動きになります。

右クリック→関係の設定 で出てくる画面
図2:右クリック→関係の設定 で出てくる画面

■ランチャなどからゲーム実行exeを起動し、その際に使用するCPUを限定する方法

これは制作側の方法であり、製作には技術が必要である。
この様な機能があるお手軽にツクールが起動できるランチャがあれば嬉しいな!(懇願の目)

結論としましては、使用するCPUを限定してやればお手軽にこの現象を回避できる、という訳です。

3 : 制作側の対策

ここからはツクール2000ユーザー(制作側)向けの内容です。
私の個人的意見であり、PCによっては効果がない場合もある為、質問・クレームは一切受け付けません。ご了承下さい。

あくまでも「できるかもしれない対策」です。

上記の対策をテストプレイ時にいちいちやるのは面倒です。
とっても面倒ですし、だからと言って無視している何処かでバグの要因になりかねません。

そこでちょっとしたアイディアです。
[キー入力の処理]でキーが連打されたかの様な反応が返ってくる = 短い間隔でキー入力が変動する、のならば、
それを条件分岐で判別してしまえばよいという訳です。

それでは具体的な例文を見てみましょう。

◆キー入力の処理:[キーコード取得変数] (SHIFT(7), 押されるまで待たない)
◆変数の操作:[取得したキー変数] 代入, [キーコード取得変数] の値
◆ウエイト:0.0秒
◆キー入力の処理:[キーコード取得変数] (SHIFT(7), 押されるまで待たない)
◆条件分岐:変数[キーコード取得変数]が [取得したキー変数]以外
 ◆イベント処理の中断
 ◆
:分岐終了

この例では[SHIFT](キーコード値:7)が押されている場合を考えています。

キーを取得した後、一度変数[取得したキー変数]にその値を記憶。
0.0秒待った後(実際には0.016秒ウェイトかかる)、再度キー入力を取得し先ほど取ったキーとあっているか取得する。

つまり、凄く短い間隔でキー入力が変更された場合にのみ処理を中断させている訳です。
これで後にキー入力を分岐として発生する処理で余計な事をするのを避けます。


さて、これで一体どれくらい効果があるのか。自分のPCで検証を行いました。

自分の作品、SHIFTキーを押しっぱなしにするとダッシュし、離している状態では速度が通常になるシステムにて検証。
SHIFTキーを押す回数、変速が行われた回数を記録し、予期せぬ変速が行われるかを調査しました。

使用する自分のPCは一般的なデュアルコアPCであり、ツクール2000の推奨動作スペックを満たしているものとした。

表:検証結果
現象 / 対策の有無 対策無しの場合 対策有りの場合
ダッシュの試行回数
(SHIFTキーを押した回数)
10 10
予期せぬ変速が行われた回数
(キー連打で予期しない動作が実行された回数)
22 0

対策無しだとキーを押しっぱなしにしてもダッシュ状態が途切れたり、途切れたと思ったらダッシュしたりと予期せぬ変速が多く起こりました。
対策有りでは予期せぬ変速は起こらず!

スッキリです!
この対策はPCによっては上手く機能しない事もあると思うので、確実に対処したい場合は前項で述べた対策をすべきである、と思います。


※以下、2010/08/16 追記分

上記ではダッシュなど、「定期的並列処理」における対策であり、通常のイベントや「自動実行」のイベントでは
イベント処理の中断」によって処理がとぎれてしまいます。

では、その様な場合でも適応するにはどうしたらよいでしょう。
なるべくツクールを触りたての人にも分かる様に説明したいと思います。

まず、問題なのは先ほどから挙げている様に、
キー入力の処理でキーが短い間隔で連打される」という事です。

これを回避するには短い間隔の後にキーを取得し、最初に押されたキーと同じかを確かめてやれば良いのでしたね。

人間は0.016秒(ウェイト0.0秒)なんて高速でキーを連打する事は難しいです。
ではそれを別処理として認識して、その時にだけ処理を短絡(無視)してしまおうというのがこの対策の狙いです。

フローチャート
図3:処理のフローチャート

処理は上記のフローチャートの様に行います。

見て分かる様に、条件分岐でaとbの値が違う=連打とみなした時は「キー入力の処理」の前に戻れば良いという訳です。
「ラベルの設定」や「繰り返し処理」などを用いて処理位置を動かしてやるなどができそうですね。

では実際にどの様なイベントコマンドになるかを見てみましょう。

◆繰り返し処理
 ◆キー入力の処理:[キーコード取得変数a]  (下(1), 上(4), 決定(5), 取り消し(6), 押されるまで待たない)
 ◆ウエイト:0.0秒
 ◆キー入力の処理:[キーコード取得変数b]  (下(1), 上(4), 決定(5), 取り消し(6), 押されるまで待たない)
 ◆条件分岐:変数[キーコード取得変数a]が[キーコード取得変数b]と同値
  ◆注釈:------------------------------------------------------------
  :  :キー入力:下
  :  :------------------------------------------------------------
  ◆条件分岐:変数[キーコード取得変数a]が1
   ◆(下キーが押された時に実行したい処理)
  :分岐終了
  ◆注釈:------------------------------------------------------------
  :  :キー入力:上
  :  :------------------------------------------------------------
  ◆条件分岐:変数[キーコード取得変数a]が4
   ◆(上キーが押された時に実行したい処理)
  :分岐終了
  ◆注釈:------------------------------------------------------------
  :  :キー入力:決定
  :  :------------------------------------------------------------
  ◆条件分岐:変数[キーコード取得変数a]が5
   ◆(決定キーが押された時に実行したい処理)
  :分岐終了
  ◆注釈:------------------------------------------------------------
  :  :キー入力:キャンセル
  :  :------------------------------------------------------------
  ◆条件分岐:変数[キーコード取得変数a]が6
   ◆繰り返し処理の中断
  :分岐終了
  ◆
 :分岐終了
:以上繰り返し

この例では「上、下、決定、キャンセル」キーのみを取り、各々のボタンに対する処理を行うという一般的(?)なひな形です。
繰り返し処理でぐるぐるキー入力処理を回っています。

何かキーが押される事で先ほどの連打現象かどうか確かめて…という処理が水色で示した部分です。
キー入力を取って同値ならば正常と判断し以降の処理へ。違うならば処理そのものを行わず「繰り返し処理」によってまた先頭に戻ってくる。

これを繰り返す事でボタンを単発で押すだけでなく、押しっぱなしにしても安定するはずです。
勿論、ウェイトなどを入れないと押しっぱなしで処理が高速におこなわれてしまう事もありますので、
そこら辺は作りたいシステムによって工夫を凝らしてみてください。

あと、この例では「キャンセルキー」を押す事でこの繰り返し処理を脱出できる様に作ってあります。
具体的、とはいかないでしょうが、これがRPGツクール2000で作ろうとしている方に何らかの形で役に立ってくれれば幸いです。