2018年6月9日土曜日

千年戦争アイギスのクリック操作がChromeで無視される件

システムアップデートに伴い以前より格段にクリック無視の頻度が上がったため, 操作の応答速度を犠牲に不具合を緩和するユーザースクリプトを書いてみました

追記&更新履歴
2018/6/17 v0.3 ユニットの誤選択が発生していた部分を修正しました

例によりこちらにリンクを貼っておきますで,  クリック不発によりゲームにならなくて困っている場合は下記に目を通した上で試してみましょう

  • スクリプトのライセンスはフリー(コードの改変なども自由, 利用時の連絡も不要)とし, 作者は本スクリプトの導入によって発生したいかなる損害についても保証しません. 導入はあくまで自己責任で行なって下さい.
  • 例によりそれほど動作検証はしていません.
  • スクリプトの導入によりゲームのマウスに対する応答が若干遅くなることから,1フレームを争うシビアなプレイには向いていません
    (クリック不発によるミスよりはましと割り切って下さい)
    そのため現状困っていない人(主にタッチ操作で行なっている方等)は本スクリプトを導入するメリットはありません

[使い方]


通常のユーザースクリプトの導入と一緒.
  • Tampermonkeyアドオンを導入します
  • こちらをクリックし, ユーザースクリプトをインストールします

    // ==UserScript==
    // @name         aigis_click
    // @namespace    defghi1977
    // @version      0.3
    // @description  千年戦争アイギスのクリック動作を緩和します
    // @author       DEFGHI1977@twitter.com
    // @include      http://assets.millennium-war.net/*
    // @grant        none
    // ==/UserScript==
    
    //NOTE:
    //ブラウザが発生させたマウスイベントをキューに蓄積し
    //等間隔にトリガすることでプレイアビリティを改善します
    //・クリック判定漏れ(2倍速・スキルトリガの失敗防止) 
    //・座標のずれを防ぐ(ユニットの誤選択防止)
    "use strict";
    {
     const c = document.getElementById("canvas");
     const queue = [];
     let pos;
     ["mousedown", "mouseup", "mousemove"].forEach(name =>
      c.parentNode.addEventListener(name, e => {
       if(e.isCustom){return;}
       e.type != "mousemove" ? queue.push(e) : pos = e;
       e.preventDefault();
       e.stopPropagation();
      }, true)
     );
     function dispatchEvent(original){
      if(!original){return;}
      const e = new MouseEvent(original.type, original);
      e.isCustom = true;
      c.dispatchEvent(e);
     }
     setInterval(() => {
      dispatchEvent(pos);
      dispatchEvent(queue.shift());
     }, 1000/60);//60fps
    }

    以下仮説(twitterからコピペ)

    DEFGHI1977
    ‏ @DEFGHI1977

    千年戦争アイギスのクリックが時々応答しないことがある件について運営に問い合わせたら所謂「おま環」との返答が
    仕方ないので不具合を緩和するスクリプトを書いてみた
    http://defghi1977.html.xdomain.jp/tech/shiro/aigis_click.user.js …
    9:57 - 2018年6月9日

    1件のリツイート
    1件のいいね
    jun@Jun-nyan(sɹǝunɾ)

    1件の返信 1件のリツイート 1 いいね

    新しい会話
    DEFGHI1977
    ‏ @DEFGHI1977
    7 時間7 時間前

    千年戦争アイギスは最近ゲームの処理速度改善を目的に内部処理(の一部)を60fpsから30fpsに引き下げたとのこと
    おそらくその絡みで起こっている不具合であろうと当たりをつけたものがこのスクリプト
    1件の返信 1件のリツイート 1 いいね
    DEFGHI1977
    ‏ @DEFGHI1977
    7 時間7 時間前

    内部を推察するにmousedownとmouseupの状況をフラグ値として保持していて, フレーム毎にこの値の変化を追うことでユーザー操作を判定しているように思われる. で, この判定をこれまでは秒間60回行なっていたところを(意図的はわからないが)現状30回行うようになってしまっている
    1件の返信 1件のリツイート 1 いいね
    DEFGHI1977
    ‏ @DEFGHI1977
    7 時間7 時間前

    ここでこの判定処理の間に極短いクリックを行うとどうなるか?
    答)フラグ値に変化がないので何も操作がなかったと判定される(クリック無反応)
    →これまでは1/60秒の間にクリックが完了した場合に限りこの現象が発生し得たが, 今回のアップデート(1/30秒間)により発生頻度が激増した
    1件の返信 2件のリツイート 1 いいね
    DEFGHI1977
    ‏ @DEFGHI1977
    7 時間7 時間前

    なので, このスクリプトではマウスイベントの発生間隔にラグを持たせてゲーム側に操作を認識させやすくしている
    もちろん, これは仮説に過ぎないし根本的な解決策でもないが, 一応プレイアビリティ上割と効果はあるっぽいので, ゲームにならない場合は試してみるといいかも(自己責任で)
    1件の返信 1件のリツイート 1 いいね
    DEFGHI1977
    ‏ @DEFGHI1977
    7 時間7 時間前

    なおスクリプトを導入すると仕組み上クリック無視が起こりにくくなる代償としてゲームの応答がほんのり鈍くなります
    シビアなプレイをしている場合は操作感が割と変化しますのでご注意下さい


    と一度は考えましたが, この仮説だと1/30sec間隔でないと効果が出ないはずで, 私の環境では1/60sec間隔でも効果があったので, 当たらずとも遠からずといったところでしょうか.
    →Chrome67以降固有の問題の可能性も拭いきれません
    マウス応答性は早いほうが望ましいため, 公開中のスクリプトでは1/60sec間隔を採用していますが, 環境によってはこの部分を1/30secなりに書き換えたほうが良いかもしれません.
    なお城プロ:REではこのような問題が発生していないことから, アイギス側においてゲームフレームワークのチューニングに見落としがあるのかもしれません.

    ーーー
    追記

    ほぼ不具合の原因が判りました(理屈が通りました)

    Pocke
    ‏ @UchiPocket

    アイギスがChrome バージョン67以降(5月30日~)で重いとかクリックしても反応しないという人はアドレスバーから「chrome://flags#site-isolation-trial-opt-out」に移動して「Site isolation trial opt-out」をOpt-outすれば改善されると思われる。
    16:48 - 2018年6月11日

    との書き込みがあったため,この内容と組み合わせると概ね次のようになろうかと思います


    DEFGHI1977
    ‏ @DEFGHI1977
    32 分32 分前

    DEFGHI1977さんがPockeをリツイートしました

    別スレッドで立ち上がったゲームウインドウ内にマウスイベントを通知する際, 発生したmousedown/mouseupイベントのキューを一度に渡している可能性がある.
    この場合, 「ほぼ0秒でクリックした」こととなりゲーム側が入力内容を検知できない
    つまり, Chromeの新機能による不具合である

    DEFGHI1977
    ‏ @DEFGHI1977
    27 分27 分前

    となると, 私のユーザースクリプトが期待通りに動作するのも理屈にあう
    つまりChromeがタイムラグ0で発生させたイベント群をもとに, 通常の操作っぽく再度イベントを発生させれば良い
    1件の返信 0件のリツイート 0 いいね

    DEFGHI1977
    ‏ @DEFGHI1977

    今回の不具合はブラウザゲー全体に発生しうる致命的な問題なので, ユースケースの精査を怠ったGoogle側に「問題の報告」からクレームを入れるべき案件である
    17:34 - 2018年6月11日
    1件の返信 0件のリツイート 0 いいね

    新しい会話
    DEFGHI1977
    ‏ @DEFGHI1977
    16 分16 分前

    もっとも, この仮説を検証するにはゲーム側でのmousedown/mouseupイベントが本当にタイムラグ0で(or同期的に)発生していることを検証する必要があるだろう
    (その際にDOMHighResTimeStampが使えるかもしれない)
    1件の返信 0件のリツイート 0 いいね
    DEFGHI1977
    ‏ @DEFGHI1977
    4 分4 分前

    またこの問題から得られる教訓として,
    「今後WEBブラウザにおいてクリック操作を監視する場合, マウスボタンのon/offを定期的に監視する古典的な方法はアンチパターン(信用ならないもの)とし, 代替として素直にclickイベントを使え」
    ということになろうかと


    そのため, アイギス(もしくはブラウザゲー)専用のChrome互換(v66以前相当)のブラウザ, 乃至は上記「site-isolation-trial-opt-out」フラグを「Opt-out」に設定した互換ブラウザを用意することでも問題は解決します.

    0 件のコメント:

    コメントを投稿