WT4.0完了したけど何かやってないと暇なので、リリース当日からWindowsストア版やらMacOS版やらを考えている。どっちも結構直さないといけない。
MacOS版のXamarin Formsを4.2から4.4に変えてみたが、何故か「テキストボックスがあると画面遷移で落ちる問題」が4.3SR1で直っていた。バージョンアップで問題が増えるんじゃなくて減ることなんてあるのか。
WT4.0完了したけど何かやってないと暇なので、リリース当日からWindowsストア版やらMacOS版やらを考えている。どっちも結構直さないといけない。
MacOS版のXamarin Formsを4.2から4.4に変えてみたが、何故か「テキストボックスがあると画面遷移で落ちる問題」が4.3SR1で直っていた。バージョンアップで問題が増えるんじゃなくて減ることなんてあるのか。
クローズドベータで出た問題点も修正できたので、Weather Typing 4.0をリリース。WT3では、WT2にあった機能の実装と各プラットフォーム対応を優先させていてずっとUIに手を付けられなかった。そっちはようやく終わったので、UIを一新できた。多少は配信に堪えられる感じになったかな。
今回背景をちょっと変えてみた。天気の背景もいいんだけど、背景が暗い方がやっぱり見やすい。唯一の天気さが消えてタイトルと乖離してしまうが、もはや気にしても仕方がない。タイピングは天気のようなものだ、とかなんとかかんとかってことで。
あとは音だけど、カウントダウン音をいろいろ試してみたが、どれもしっくりこないのでとりあえず保留。
この後はどうしようかな。とりあえずWinストア版作って、MacOS版作ったら、ワード自動生成の研究に戻るか。その前にVectorも登録しないと。
追記。Windows 7はサポート範囲外にしたがたぶん動くはず。手元に環境がないので、何か問題があっても対応できない可能性が高い。実はWindows 8.1とかWindows 10 32bitとかもテストしきれないので試してはいない。こちらは環境はあるので問題への対応は可能。
Twitterで書いたとおり、WT4.0はテスト完了。あとはクローズドで試してもらったりWebサイト更新したりで来週中にリリース予定。
で、いい機会なのでウェザタイの指標を測ってみた。この辺の値を記録しておくと次のバージョンで便利なので。
結局分かりやすいステップ数で考えると、もろもろ含めてウェザタイのソースは約10万行。
CLOCの結果。
言語 | ステップ |
---|---|
C# | 67661 |
XAML | 8873 |
XML | 7049 |
Java | 6726 |
PHP | 2434 |
C++ | 2382 |
C/C++ Header | 1967 |
JavaScript | 325 |
HTML | 59 |
SQL | 37 |
Perl | 9 |
合計 | 97522 |
クライアントがほぼC#/Xamarin Forms、入力やI/O周りでC/C++を少し利用。XMLはresxのことなので、若干自動生成分がある。ランキングやロビーのサーバがJava。Perl/PHPはランキング、ワードサーバに使ってたけど、今はほとんどJavaになっている。
こう見ると、20年とはいえなかなか1人で作る量ではない気がする。大手で作ろうとすると軽く1億円くらいかかるのかなあ。1億円売り上げるにはタイピング界の人口が・・・とか考えていくといつかのジェイブログさんの書き込みで「タイピング企画が通らない」と言っていたのもなんとなく分かりますね。
まあ、WTの場合、商用に比べてOSSとかフレームワーク使わずに一から作ってる部分が多いので、その分多くなってるかも。結局製品寿命が長いことを考えるとそうせざるをえなくて、20年前と変わってないのは結局Raw SocketとかDirect Inputとかそのくらいしかないような気はする。Xamarin Formsもいつまでメンテされるか分からないけど。
WT4.0の開発はRTC 2019の後に始めたから、企画、設計、実装、テストで約2ヶ月。RTC 2019版からWT4.0の改造が約1万行だったから10%直したことになる。
レグレッションテストの全件数が576件で、うち自動テストが455件(約80%)。前回作ったAppiumによる自動UIテスト、やっぱりテスト効率がいい。今回かなり本体を修正したのでテストコードも結構直したけど、これがなかったらテストにあと1ヶ月くらいかかる気がする。テストコードは直し終えたので、Android版とか作るときは(理想的には)テスト実行するだけでいいし。
で、WT4.0開発でレグレッションテストした結果は不良32件。これが多いのか少ないのかは分からないけど、次回の参考にはなる。
WT4用に通信の改善を実装。せっかくなのでWTの通信処理を詳しく書いてみるか。ラグとか同着とかの理由を知りたい人もいるかもしれないし。
WT3までは、プレイヤ全員のメッセージが届いたら全員の入力を確定して、次のフレームのメッセージを送るという実装をしていた。以下の図は「ABCDEF」をAとBが打ち込んでいる例。自分のプレイヤが打った文字は遅延なく画面に反映し、他のプレイヤが打った文字はメッセージが届いてから画面に反映するので、AとBでは見ている画面が違う。ただし、内部的には自分と他のプレイヤのメッセージがそろったときに時間を進めるようにしているため、AとBの同期がとれている。ここで、いくつか問題がある。
WT初期は電話回線だったので通信対戦ができるだけでもよかったが、さすがに配信とかを考えるともう少しなんとかしたいよね、ってことで、WT4ではもう少し通信量を上げて対策をしてみる。下の図で、点線の矢印が新たに追加したもの。入力があったらとにかく相手に送りつけて画面に反映するようにした。ただし、あくまでも画面表示だけの変更で、内部処理は変えない。速度やワード取得の判定は今まで通り全員のメッセージを待つので、今までと変わらない。
上記の問題点では、1と2だけの対応になる。内部処理でローカルPC上の絶対時間を見て判定するようにすれば3と4も改善できるし、工夫次第で観戦モードではラグが発生しないようにもできそうなのだが、試した感じ、割とここまででも十分効果がありそうだったので、WT4ではひとまずここまで。
ちなみにこの辺り、約20年前に独力で実装した部分なので、今のネットゲームから見ると全然なってないんだろうな、と思って「オンラインゲームを支える技術(WEB+DB PRESS plus)」なんかを読んだりしてみたけど、割と合ってて安心した。
Weather Typing 4.0の開発。長いことプラットフォーム対応やテストプログラムとかやってたけど、一段落したので、ようやく見た目とか機能面に着手できるようになった。公開はもう少し先だけど開発は順調。次バージョンがどうなるか軽くメモ。
RTCで出ていた不良のメモ。
この辺りは今日RTCの動画見ながら原因調査したけど、推理力と観察力と地道な捜査が必要で、プログラマの能力はプログラムだけじゃなくてこういった能力が大事だというのを感じる。
で、あとは大会用にホスト兼観戦モードみたいなのを追加するのと、通信のラグ改善を入れたらテストして完成かな。さすがに2/16のWarriors of Typingには間に合わないか。
あ、あとカウントダウンの音か。一応書いておかないと怒られる。
タイピング日本一を決める大会「REALFORCE TYPING CHAMPIONSHIP 2019」。12/1に行われたオフライン大会を観戦してきた。もちろんe-typingによる予選にも参加して本戦を目指したが、全然レベルが足りなかった。去年までの観戦記:RTC2017、RTC2018。
Youtube配信しているので是非。5時間半と超長い・・・長く楽しめるのでお徳。そして11/12発売のREALFORCEテンキーレスMacキーボードも欲しいですね。宣伝は基本。
以下、タイパー視点、開発視点、ビジネス視点、e-sports視点で。長いので興味のある部分だけでも。
まず会場。RTC2017は東京ゲームショウの東プレブース、RTC2018はRED BULL GAMING SPHERE TOKYO、今年はSTORIA 池袋。個人的な感想としては、ゲームショウ会場は露出は高いけど競技にはなかなか向かず、RED BULL会場は堅い雰囲気で会場内が静かになっていた感じがするが、今回の会場は開放感があって盛り上がりやすかった。さらに池袋駅前のタイトーステーションにある大型ビジョン。途中その絵を見たくて外観戦してみたが、大画面にウェザタイが映っているのは感動。さすがに街行く人が興味津々ってわけではないけど、対戦が始まると何だこれ的に見ていく人がちらほら。
対戦内容は例のごとく他の人の感想に任せて少しだけ。やっぱり応援する選手を決めた方が面白いので、現ウェザタイランキングでJISかなQwertyともに3位、WTといえば、の、ひろりんご選手応援で臨む。最終戦、完全にmiri選手と互角、ワード同時取得の応酬、4-1から4-4への追い上げ、すごい盛り上がりだった。今まででも一番の歓声。このGrand Finalを見るために18年間Weather Typingを開発してきたといっても少ししか過言ではない。
あと気になったのははやとぅ選手。U-22最後の1ワード、94%で打ち終わらないように止めていたが、相手が96%から数回ミスしたのを見て打ち切って優勝を決めた。また、本戦2回戦でも同じように相手が95%から数ミスしたのを見て打ち切っていた。あれは、何打鍵中何打鍵ミスしたか、自分側も相手側も計算するウェザタイ算、RTC算か?をマスターしているのだろうか。
前回の宿題事項だった以下の点については解消。
以下の点については課題が残っている。
次に今回の変更点。今回、ウェザタイ本体から大幅に仕様変更している。実は大分前からお話を伺っていたので、時間を掛けて作り込んだ。
次に今回の問題点。
第3回目となるRTC。いつも思うけど商業的に成り立っているのか不思議。会場貸し切り、大型ビジョン、賞金、お土産まであるし。来年も開催されるかどうか、社内で企画を通せるかどうかはYoutube配信の視聴数にかかってくるのか、毎年新製品が出るなら採算度外視が許されている企画なのか、とかビジネスモデルを想像していたら、「タイピングアドカレ」でジェイブログ「タイピングを流行らせて多くの人が楽しむにはビジネスとして扱う事が必要な件」が公開されていた。だいぶ具体的に書いてますね。ウェザタイと違って東プレさんは慈善事業じゃないので、来年以降も企画を通しやすいように、何かしら裾野を広げる活動で実績を作って応援していかないと。
そういう意味では、この前のN高等学校 第二回ネット運動会は運動会という特性上、タイピングマニアは出場できないので一般の人が気軽に楽しめるものになっていてよかった。タイピング速度もそこまでではないのでワードの面白さを楽しんだり、逆に新鮮。別にウェザタイでなくてもいいんだけど、こういうタイピングを使った何かが増えていくとよいですね。
ちなみに「ジェイブログ」から。
WeaterTypingは無料で公開されているので、費用がかからないのが当たり前と思ってる人が多いですが、開発者に還元すれば、モチベも上がりますし、より良いタイピングソフトになっていく可能性が高いです。
その通りなんですが、私の場合、ダイレクトに収入になってしまうと表向きの職業にめんどうな影響があるのでちょっと。例えば自作ワードを作って公開するとか、面白いリプレイを公開するとか、対戦動画を投稿するとか、ウェザタイの世界を広めるような還元があると嬉しい。英語ワードとか・・・あっ。まあウェザタイ側の機能も不足してるんだけど、この辺はニワトリとたまご関係。
ネット運動会のときにFortnite他のe-sports実況を見たが、ゲームのルールは複雑でも、ルールが分かってくるとその複雑さが面白くなってくる。そういう意味ではタイピングは単純すぎる感はある。ネット運動会で司会者の方が100m走に例えていたのはなるほど。ただ、一般的なe-sportsゲームだとなかなかゲームファン以外にアピールするのは難しいけど、タイピングは一般の人にもアピールできる可能性はあるのかな。大型ビジョンでも、他のゲームに比べると、お? って見る人がいる感じ。
なお今後はタイピングマニア向け機能を増やすより、配信の見やすさや大会運営が楽になる機能を重視していくと思う。悪く言えば打ちやすさよりも分かりやすさを優先することも多くなる。要望等もそっちにからめて利点を説明してもらえると検討するかも知れない。
いろいろな視点で書いてきたけど、結局、面白かった。去年の、miri選手がloserに落とされて勝ち上がったドラマを超えられるのか、と思ってたけど、今年は逆にmuller選手がloserに落とされてlosers決勝まで勝ち上がったり、Grand Finalの盛り上がりも去年以上だった。大会の演出も、手元カメラが増えたり画面も見やすくなっていて、まだまだ進化しそう。
てことで、選手の皆様、運営の皆様、今年も素晴らしい大会ありがとうございました。来年以降もあるといいなあ。
「N高等学校 第二回ネット運動会 ~esports Festival~」を観覧した。さいまえでコメント打ちながら視聴したけど、全体的にゆるくてニコニコ感が心地よい。生徒が会場にいないから先生宣誓でいいや、は草。
てことで、開始前は、今回の競技の並びにWeather Typingが入るのはどうなのか、盛り上がるのか、と思っていたが、なかなか面白かった。やっぱり初見だとワードのインパクトがあるようで、「この例文考えたヤツ出てこい」コメントは誉め言葉。ウェザタイのワードは真面目に変なことしてる感があって、ニコニコの雰囲気とは合う気がする。シナリオ的にも、タイピングを白が圧勝したことで後のドラマ性を高めるのに貢献できた。12月生まれなので赤が逆転するともっとよかったけど。
タイピング的には、早い人を後ろに持ってきていたのか、最終戦は550kpmくらいまで出ていた。来週の「Realforce Typing Championship 2019」は1000kpm超えまで行くんだろうけど、このくらい一般人にも届きそうな雰囲気の対戦もいい。Weather Typingの頂点が気になる人は、12/1の配信を見るべき。よし、自然に宣伝できた。
ウェザタイの改善点。やっぱり画面まわりと、遅延が見えすぎる問題かな。画面はRTC 2019版を参考に考えていくとして、あとは通信遅延。第一戦、遅延が大きくて大丈夫かな、って思ったけど二戦目以降は割と安定してたかな。どうしてもプレイヤーの環境に依存する問題はある。改善案として、ずっと前から「リアルタイムから1秒くらい遅れるけどスムーズに描画する観戦モード」っていうアイデアはあって、今回実装するのに必要なモチベーションが結構たまったのでもう一声ってところ。
今はe-sports知らなすぎというのもあり、せっかくなので全部見て勉強した。ゲーム内容については知らなさすぎてコメントできないのでシステム的なところだけ。コンパスは、あれは大会モードなのかな。プレイヤー全員の画面を切り替えられるようになっていてよい感じ。クラッシュ・ロワイヤルは1対1だからかも知れないけど現在の状態が凄く分かりやすくて、私でも最後はルールがなんとなく分かるようになった。Fortniteはどうしても1人を追う感じになるのかな。誰がどこにいるか俯瞰するモードがあったりしないのかな。いずれにしてもe-sportsとしての工夫が盛り込まれているのでウェザタイにも取り込んでいきたい。
ネット運動会、なかなか見応えがあった。配信を見る限りでは通信トラブルなどもなかったようなので安心。視聴数も最終的に12000くらいになってて、こういう場でe-sportsとしてのタイピングを広めることに少しでも貢献できるといいですね。
運営の皆さんありがとうございました。
WT RTC2019版の正確性の仕様についてメモ。
WT RTC2019 v06版では、正確性の仕様がWT本家およびRTC2018版と変わっている。WT本家では、画面表示時の正確性はC#のdouble-文字列変換で少数点1位まで表示したものに従う。四捨五入っぽいけど正確なところは不明。で、変換の詳細が分からないと95%未満で黄色い背景にすることは難しいので、RTC2019 v06では少数第1位で切り捨てることにした。結果、最大0.05%ほど正確性が下がる。例えば、最後のワード、最後の文字で、今1999打鍵105ミスだから、あと1文字はミス可能、全速力で打とう、といったギリギリの計算をしていると、106ミスで95%を割ってしまい、負けてしまうので注意が必要。
ちなみにWT本家への反映予定はない。入れるにしても過去との互換性等、いろいろ検討しないと。
既に各所で告知されている通り、12/1の「REALFORCE TYPING CHAMPIONSHIP 2019」のオフライントーナメントでWeather Typingが使われる。で、今日告知があったが、11/24に行われる「N高等学校 第2回 ネット運動会~esports Festival~」の競技の一つにWeather Typingが入った。RTC2019は現地参加予定、ネット運動会の方もネット配信あるので楽しみ。
両方とも事前に話を聞いていたが、日程かぶってなくてよかった。ていうか、日程かぶりを心配するほどWeather Typingが使われることにビックリだ。ゲームに詳しい人に聞く感じ、RTC2019会場の大型ビジョン(タイトーステーションのところ)はゲーマー界隈では知られているらしく、そこに映るのは結構スゴイらしいし、ネット運動会もFortniteと並んでいるのはスゴイことらしい。まあ、タイピングでe-sportsというのが(TODを除いて)商業ソフトにないだけではあるけど。
ちなみにRTC2019の方はOEM的に配信特化した版を提供している。運営の方にはWeather Typing本体にも配信用のデザインを反映させて欲しいとは伝えている。「Warriors of Typing」も続けて頂けているし、配信用画面とか観戦機能を付けて4.0にできるといいなあ。
関西のウィークリーマンション用に以前大阪で買ったUQ WiMaxSpeed Wi-Fi HOME。神奈川に戻って光回線が使えるようになったので不要になった。途中で使えなくなっても2年契約する覚悟で契約したので、どうしような、ってことで機種変。Speed Wi-Fi NEXT W05にしたので持ち歩けるように。これでラズパイとか外で使うのに便利になる。
関西にいる間に行っておこうと思っていた博多まで行ってみた。目的はやはりヨドバシカメラ博多。
新幹線とヨドバの共演。ワクワクですね。
概観はこんな感じ。大阪や京都のようなインパクトはないけど、中は普通に充実してた。
まあせっかく行ったので中洲~天神辺りをブラブラしたり明太子を買ったりはしたけど、例によって日記の主旨と外れるので省略。日帰りでも十分面白かった。福岡県のネットイメージから銃撃戦を覚悟していたんだけど普通だった。
さて、いつの間にか琵琶湖とか名古屋も行ってみたので、これで関西にいる間に行きたかったところはコンプリート。ヨドバシカメラでいうと15/23店舗を制覇。うち東京近辺の4つはいつでも行けるので、ちょっと気合いを入れないと行けないのは仙台、郡山、新潟、宇都宮か。
ちなみにヨドバシカメラ名古屋。特筆することがなかったので日記にも挙げてなかった。
Windowsデスクトップ版は、いつかのWindows 10のアップデートでUIがおかしくなった問題の修正。これだけでバージョン番号をあげるとWT4.0に近づいてしまうのでなんとなく保留していたのだが、いろいろ大会に使われてきてもいるので、そろそろ公開しないと。
MacOS版は、本当は対戦サーバに接続する機能だけ追加しようとしていたのだが、結局ほぼWT3.6までの機能は入れた上で公開した。当時のソースコードを再度ビルドすると、新しいMacOSライブラリでは全然ちゃんと動かなくて、Xamarin Formsを4にしたり、いろんなバグを回避をしたり大変。結局最新ソースを使うしかなかった。
UIスレッドの問題は面倒だけど回避は簡単。いろんなところにUIスレッドコールを追加して解決。エディットボックスの問題は、その時点でもうMacOS版を捨てようとしたくらい致命的。バグは増えても減ることはないので今後も修正されることはないし。でもあがいた結果、画面遷移の直前にエディットボックスを含むちょうどいい領域を非表示にすることでたまたまうまく動いたので、それで回避することにした。
そしてリリース版を作ろうとしたらVisual Studioの署名オプションがDisableになっていて付けられない。MacOS Developerのサイトから証明書をダウンロードしたりいろいろしたけど、結局サイトからダウンロードする必要はなくて、XCodeのオーガナイザで追加することでVisual Studioの署名オプションが有効になった。
で、WT3.6で入れた背景画像選択機能がサンドボックス化で動かなくてトークン化したり、初回起動時に権限を聞かれるようになったりしつつようやくpkg化完了。したんだけど、pkgをインストールしたらもう二度とpkgからもMacOS Appストアからウェザタイをインストールできなくなった。トラップ。3.7をリリースしたらストアから入れられるようになったけど、これだとバージョンアップのテストが不可能。やっぱりMacOSは一般の開発者に厳しい。
最低限月1回の投稿を目指しているので、そろそろ何か書いておこう。日記じゃなくて月記になってるけど。
ウェザタイの開発はiOS/Mac版のAppiumによるテストをやろうとしてるけど、iOSはそれだけで何ヶ月もかかりそうだし、MacはAppiumの機能が少なすぎておそらく無理。いいかげんプラットフォーム対応は終わらせて新しいことをやりたい。
上にも関連して、最近は開発に時間がかかりすぎる気がしていて、もう少しなんとかならないかな。てことで関数型言語の勉強を進めている。ただ、関数型言語は数学の素養がないとちゃんと理解できないので数学を勉強中。
もともと、物理シミュレータとか暗号論の勉強でちょっとずつ数学を勉強していたが、4年くらい前に「数学ガール」を読んで面白くなった。大学の頃は、数学の本を読んでも定義と定理と証明ばっかりで誰が理解できるのか不思議だったけど、「数学ガール」でだいぶ教科書の読み方が分かってきた。Haskelは圏論をベースにしていて、さらに圏論を真面目にやるには、群論などをちゃんと理解しないと言ってることが分からない。てことで数学のいろいろな分野に手を出しているところ。
さらに平行して人工知能も勉強中。こっちは具体的にウェザタイに活かしたいものがあって、ワードの自動生成とか、人間みたいなCPUの作成とかができると面白いかな。で、「ゼロから作るDeep Learning」を見つつ、ウェザタイに使うためPythonで書かれたものをC#で実装している。1巻は既に実装が終わって、今2巻のRNNあたりを実装しているところ。ウェザタイに使うには時系列が必要なので。
人工知能の本を読んでいると脳の仕組みとはかけ離れた方向に向かっているので、今まであまり勉強したくなかったのだが、部分的には人間の脳と同じようなことが再現できているようなので、とりあえず追いつくために勉強している感じ。うまく動かすために、脳を研究するのではなくて、数学的な仕組みやパラメータで解決するので、これを進めても脳の実現は無理そうな気がするけど、まあ特定の問題を解くのには便利そうなのでこれはこれで使っていこう。
あれ、電子工作やってない。。。
ちょっと長めの夏休みってことで関東に行っていて帰ってきた。もう関西に「帰ってきた」という表現になるくらいだ。
開発環境もあんまりないのでひたすら人工知能の勉強。といっても普通のディープラーニングとかではなく脳科学からのアプローチだけど。
普通のディープラーニングもそろそろ実装できてきたのでウェザタイへの応用を考えよう。
神奈川の家にしばらくいたので、Amazon Prime Videoでシリコンバレー第5期を一気に見た。関西の家だと通信に制限があるのでちょっと見づらい。
第4期はリチャードが闇落ちして犯罪を犯したけど、運良く捕まらずにラッキー、で終わった。そのストーリーはどうなのか、第5期はもっと酷いのか、と思っていたけど、第3期以前のノリに戻った感じ。ピンチに陥って誤った道を進みそうになるけど、ギリギリ正しい道を選んで、運良く助かる、っていうのの繰り返し。マンネリ気味ではあるけどやっぱり面白い。
でようやく「新しいインターネット」に動きが。ラスに説明したとおり、P2Pを基本に、世界中にある端末のストレージを共有するインターネットって感じかな。ギャビンベルソンの懸念するデータゲドン(くだらないデータが増えすぎてデータ量が爆発する)を解決することはできるかもしれないけど、理念であるGoogleとかMicrosoftに支配されない世界とはあんまり関係ない気もする。個人的には、今のインターネットは極度に商用に偏ってもはや無価値になってきているので、昔の集合知みたいなインターネットに戻るといいんだけど。てな感じでシリコンバレー、今後どうなっていくのか。ていうか続くのか?
Android版Weather Typing。Android版というか全プラットフォームでネイティブライブラリを使っているのだが、Visual Studio Xamarinを使ってアーカイブを作るとx86/x64のどちらかにしかネイティブライブラリが入らない。仕方ないので今までは64bit版だけを入れていたのだが、おそらくx86のAndroidでは起動エラーになっていたはず。なので今回はもう64bit専用にして32bitはインストール不可にしたのだが、掲示板で32bit版のOSに関する報告があった。
いくつか調べてみたが、Xamarinの公式でも困っている人がいて、Xamarinとしての解決策はなさそう。Androidとしての解決策として、32bit用と64bit用のapkを両方登録することができるらしい。なので今回、32bit用のネイティブライブラリを入れたapkを登録した。ただ、Xamarinの制約?バグ?として32bit版専用のapkを作っても64bit用のmonoライブラリも入ってしまう。なので、GooglePlayに、1つVersion Codeを下げた32bit版を登録してみた。これでどうなるか。
Weather Typing 3.6 Android版を更新。ロビー参加とネット対戦に正式対応。今までホストを作るのが困難だったので隠し機能扱いにしていたのだが、サーバクライアント式にしたことでようやく正式対応と言えるようになった。
今回、Android 64bit版のみ対応にしてみたけど大丈夫なのかな。前のバージョンでも32bit版ネイティブDLLを入れていなかったのでエラーになっていたはずで、64bitのみにした方がややこしくないかなってことで。
Xamarin+Appiumによる自動テストは、入力関係はうまくいかなかったりしたが、70%くらいは自動化できた。あとはMacOSとiOSの自動テストができるとテスト効率が上がる。
ちょっと更新が遅れたけど、高知県のPCショップエレパさんの2019エレパ夏祭り内でタイピング大会が開かれ、Weather Typingを使って頂いた。
メールで連絡を頂いたものの高知県ということでどうかな、と思いつつツイートしてみたところ、タイピングAGOGOのおはようさんが高知県在住ということで参加された模様。しかも優勝してるし。Twitterすごい。
大会の詳細もブログにまとめられていて参考になる。RTCはかなりガチな競技会になっているが、こういう場の場合、対戦だと時間拘束もされるし、単純にスコアを競う感じの方がよいってことかな。もっと派手な見た目のソフトの方が一般受けはしそうだけど、その中でウェザタイを使ってもらってありがたい。
Windows 10のMay 2019 Updateを入れたら、ウェザタイのタイトルや結果画面のListViewが崩れるようになった。
調べてみたところ、ListViewの表示がちょっと遅れて、最初の行を追加するときはListViewの幅が分からず最小の幅になって、その後の行はListViewの幅が確定してちゃんと表示される、っぽい。なので、最初の表示だけListView.SizeChangedが来たときにListViewItemを追加するようにした。もうWPFは廃れていくだろうし、適当でいいや。
ウェザタイのiOS/MacOS版のアップデートをするにあたって、今まで使っていた2012年のMac Book ProではmacOS Mojaveを入れられないという問題が。さすがに7年前に買ったやつだしなあ、ということで買い換え。
開発に使うので最近発売されたMac Book Proというのは決めてヨドバシカメラへ。7年前は13インチにしたんだけど、店頭で触ってみた感じだと15インチでも2012年の13インチと同じくらいのサイズ、重さに至っては15インチの方が軽い。なので15インチにしてみた。約30万円。去年買ったSurface Book 2とほぼ同等のスペックだけどSSDが256GBな分(?)多少安い。
とりあえず開発環境を整えて、iOSとMacOS用XamarinアプリをビルドしてAppium経由で起動できるようにした。
Surface Book 2+Mac Book Pro 2019の絵。
これで、神奈川の家用にDELL機+2012年Mac Book Pro、関西の拠点用にSurface Book 2と2019年Mac Book Pro、出張用にSurface 3で、全部で5台になった。多い。
Weather Typing 3.6を公開するにあたって、UIテストの自動化を研究していた。今、ウェザタイのリグレッションテストの項目が約2500件、WPFだけで500件くらいある。これだけあるとテストだけで数週間かかってしまい、何か修正してもテストがめんどうで公開をあとまわしにしてしまう。人を増やさずになんとかならないか考え続けた結果、UIテストがそろそろ実用的になっていそうなので、やってみた。
Webの世界ではSeleniumがよく使われているが、それをデスクトップアプリやモバイルアプリに使えるようにしたAppiumというフレームワークがある。バイナリだけでテストができるので、C#+Xamarin.Formsで作ったアプリでも、C#でテストコードを書いて、マルチプラットフォームでテストできる。
で、まあいろいろ苦労はしたが、最終的にWPFのテストは77%の自動化ができた。しかも面倒なテストはほとんど自動化できたので、手動のテストを含めても、早ければ1日でテストが終わる感触。
なお、今回はWPFなので、WindowsAppDriverを使用。Windowsストアアプリも同じものが使えるはずで、Android他はまた違うAppiumのドライバを使うが、テストコードは基本的に共有ができるはず。
Palm OSのアプリを作ってた時代は、グレムリンテスト(モンキーテストの自動化)くらいしかなくて、とてもちゃんとUIのテストはできなかった記憶があるけど、RPAも実用的になっている今の時代、以下のような項目くらいは自動化できるようになっていた。
具体的には、プログラム上でUI部品にIDを与えておくと、実行時にそのIDからテキストを取得したり、クリックしたりできる。さらにテスト自体はプログラミング言語を使って書くので、ロジックは入れ放題。プラットフォーム依存になるけどファイル操作なんかも普通にできるので、かなり自由度が高い。
逆に、どうしても自動化できなかったのは例えば以下の項目。そりゃそうだろうね、っていう感じ。頑張ればできるかも知れないけど手動でやってもたいしたことはない。
UIテストをやる前は、結局目で見ないとおかしいことに気付かないから意味がないかな、と思ってたけど、Appiumの場合、実際にマウスでクリックしたりキーボードを入力したりするので、手動でテストするのとそんなに変わらない。テストスピードがあまり早くないのもあって、テストの様子を見ていればレイアウトが変になっていたりしても割と気付く。
手動ではどうしても確認にミスが出るので、むしろ自動の方が正確だし、手動の時は全組合せのテストは不可能である程度抜粋にせざるをえなかったが、自動なら何も考えずに全組合せテストしてもたいしたことはないので網羅的になる。
メモ。今回のUIテストでは以下のことを気を付けて作ってみた。
ついでに、WindowsAppDriverでハマったこと。
しばらくWeather Typing 3.5を開発版としていたが、開発版のままにしておくデメリットが大きいので、正式版として公開した。Xamarin Formsがバージョン同じままバイナリが変わる問題もあって、リビジョンアップができないのでマイナーバージョンアップにしている。
本当はストア版やMac/モバイル版をアップデートしてから正式版にしたかったのだが、もうこっちは少し時間がかかりそう。
あんまり下手なことはかけないのでTwitterかブログか迷ったけど、折角なのでこっちに。TwitterでGANGASさんの、タイプウェルランキングが6/1で更新終了という話が。TODとタイプウェルがなければウェザタイはここまでになってないので、感謝。思わずタイピング本のインタビューを読み返したりした。ウェザタイの適当なランキングと比べて、あの厳格なランキングを20年くらいメンテし続けているのはすごい。
ウェザタイはどうなるかな。メンテだけなら負担はほとんどないので、ランキングやロビーは続けようと思えばいつまでも続けられる。ただ、プラットフォームについていくには、定期的に作り直しが必要になるので、WT2のときみたく他のソフトウェアを作り始めてしばらく放置はありうる。あとは、何かあったとき用に、ボタン一つでソースコードを公開する仕組みか、ランキングと対戦で不正ができないようにした上でオープンソース化できる仕組みを編み出さないと。
Visual Studio 2019に入れ替え。とりあえずウェザタイプロジェクトを開いてみたが、プロジェクト設定を最新のプラットフォームにしたり何度かリビルドして、とりあえずビルドはできた。
Channel 9の動画で見たが、Xamarin.FormsのXAMLがデザイナーで表示できるようになった。デザイン時だけのリストを入れたり、かなり改善されている。
で、XAMLデザイナーを使うためにはXamarin Forms 3.6にアップグレードする必要があるようなので、嫌々アップデート。ただ、今回増えたバグは、Xamarin Forms WPFのリストボックスのスクロールバーが、常に表示されるようになったことくらい。思ったよりバグは増えなかった。
で、スクロールバーの件はListView hide scroll view scroll barsで作り込まれている。スクロールバーのhidden/visibleが指定できるようになったみたいだけど、何故かWPFでは今まで使えていたAutoが使えなくなっている。なので、例のごとくListViewのRendererで以下を指定して回避。
System.Windows.Controls.ScrollViewer.SetVerticalScrollBarVisibility(Control, System.Windows.Controls.ScrollBarVisibility.Auto);
Twitterで東京理科大の近代科学資料館がリニューアルで一時休館という話が流れてきた。 近代科学資料館自体知らなかったけど、調べてみると古い計算機を置いているらしい。これは見ておかないと。ってことで行ってみた。
以前アメリカのComputer History Museumへ行ったときはものすごい量の計算機があって一日いたのだが、そこまではないよね、って思っていたけど、思ったより充実していた。また、Computer History Museumに行った後、コンピュータの歴史の本も何冊か読んだので、これがあれか、ってなって面白かった。
見所としてはUNIVAC(世界初の商用コンピュータ)とか、IBM 5110(あのIBN 5100の元ネタの後継機)とか。UNIVACはComputer History Museumではガラスの向こう側であまり見えなかったけど、ここではそのまま置いてあってだいぶ詳しく観ることができた。あとは、Altair 8800(世界初のパーソナル・コンピュータ)は初めて見たけど、思っていたより大きい。パラメトロン(真空管からの移行期に、トランジスタかパラメトロンか、みたいな話だったかな)もどんなものかな、と思っていたけど、外見からはあまり分からず。去年企画があったらしいので観たかったかも。
あとは、計算尺は自宅にあるけど使ったことないなあ、とか、タイガー計算機(ハンドルを回して計算する機械)とか、これも実家にあったような気がするTK-80とか。 Bush式アナログ微分解析機 。アメリカでバベッジの解析機関のデモをやっていて、それは1部屋使った超巨大なものだったが、それとは別の話なのかな。この辺りは後で調べてみよう。
久々に東京に帰ってきたのではっぱさんと情報交換。はっぱさんが3Dプリンタを入手して以前モデリングデータを渡していたのだが、ようやく完成品を受け取ることができた。
カロリーメイト! これはどう見てもカロリーメイトですね。色合いがチーズ味にぴったり。写真だと分からないけど、軽さとか手触りとか色合いとかがなかなか良い感じ。とりあえずカロリーメイトしか食べない人に見てもらったところ、本物かと思った、というコメントをもらった。
こういうのを簡単に作れるとなると、電子工作のパーツも作ることができて、いろいろ捗りますね。
ずっと前から気になっていたSonyのデジタルペーパー。Kindleを買ったときにあまりに紙に近くて感動したので、もっと大きいのがあればいいのに、と思っていた。で、デジタルペーパーはまさにそういうデバイス。でも8万円って高いよね、と思っていたらいつの間にか手元にあった。
PDFしか見られないのでだいぶ用途が狭いのだが、読みたいPDFがあるならかなりよい。まずでかくて薄くて軽い。雑誌でも拡大しないで普通に読めるし、本より軽い。表示切り替えはまだ遅いけど、Kindleと変わらないというかKindleよりは早い気もする。
あとどのくらい待てば電子ペーパーでAnalog Book Readerを動かせるようになるかな。液晶に近いくらい反応速度が上がって、電子書籍のストアとデバイスの組合せが自由になって、Analog Book Readerくらいの使い勝手が実現できれば、紙の本はいらなくなるのに。
とりあえず、これでたまっているSoftware Designを読めるかな。液晶だと目が疲れるからなかなか進まなかった。
あとは、電子メモ的な使い方もできるので、Boogie Boardの代わりに使えるかな。Boogie Boardの手軽さには勝てないと思うけど、白地に黒なのと書いたメモを保存できるのは魅力的。
3/2のWarriors of Typing #0を観戦。たのんさん企画のタイピングオンライン対戦で、ウェザタイを使ってもらっている。定期的にやっていきたいとのことなので、今後にも期待というかウェザタイも頑張らないと。配信はTwitchで観られるので是非。
最初の話では、WT3.5でポート開放が不要になったのもきっかけということだったが、確かにこういう形だと、ポート開放があると難しい。いくつかの試合が同時進行なのでホストを一人でやることはできないし、接続が安定しないと大会がその都度中断されてしまう。
たのんさんも今回は#0でお試しと言っていたが、ウェザタイ的にもWT3.5が本格的に使われるのは初めてなので、サーバ負荷等、貴重なデータを取ることができた。大会中のサーバ負荷についてはCPU/Disk/Traffic特に問題なし。不安だった同時対戦についても、2人対戦を4試合同時くらいでは問題なし。むしろ、既に安定していると思っていたロビーサーバの方で対戦接続時にエラーが発生する現象があり、開始時間が遅れた。てことで今日、昔作ったロビー負荷テストクライアントをC#に移植してテストして、かなり負荷をかけてみると同じ現象が発生した。対戦開始時、対戦相手を検索するときにプレイヤー情報が入っていないときがあってエラーが出る。ただ、大会ではこんな負荷はかかってなかったしなあ、と思ってその視点でログを解析した結果、ようやく原因が判明。ロビーに入るときにパスワードが間違っているとクライアント側でエラーメッセージが出るのだが、これにOKを押さないと、ロビーサーバ上、プレイヤー情報がないメンバーが入ってきてエラーになってしまう。その人がOKを押せば直るのだが、その状態で放置するとその間は誰も対戦ができなくなっていた。たぶん初期からの問題。
あとはRTC2018でも起きていた、対戦が終了すると対戦相手がいなくなってしまう現象がまだ起きている。一応WT3.5で怪しそうな所は直したのだが、まだダメみたい。現象が発生したときの全員分のリプレイでもないと直せそうにない。
で、VTuber配信やオフライン大会など、新しい使い方が出る度にいろいろ改善したいことが出てくるが、今回もいくつかある。開発が間に合ってないけど。
ちょっと前からWeather TypingのWindowsデスクトップ版以外の更新をやっているのだが、テストが2300件くらいあって、さすがにテストが大変。てことでUIテストの自動化を本格的に調査。1週間くらいかかってようやく見えてきたのでメモ。ちなみにAndroid/UWP/WPFは実験成功して、Mac/iOSはまだ試せていない。
UIテストはいろいろな方法があると思うけど、マルチプラットフォーム対応だとAppiumがよさそう。Appiumは、WebのUIテスト自動化Seleniumと同様の方法でモバイルアプリのテストをするフレームワーク。サーバクライアントになっていて、クライアントでテストコードを書くと、サーバにJSON形式のコマンドを投げて、サーバからアプリのUIに向かってキーボードやマウスのイベントを投げてくれる。AppiumのサーバだとAndroidとiOSがテストできるが、Windows Application Driverを使えばWindowsのWPFやUWPもテストができる。クライアントについては、Pythonなどでやるのが普通かもしれないけど、Appium.WebDriverを使えばでC#で開発が可能。
まとめると、C#でUIをテストするコードを書いて、Appiumのサーバを起動すればAndroid/iOSのUIテスト、Windows Application Driverを起動すればWPF/UWPのテストが可能ということ。さらに一工夫いるが、Xamarin.Formsのアプリもテスト可能である。
まずはEffectの属性。プラットフォーム共通。
public static class TestEffect { public static readonly BindableProperty NameProperty = BindableProperty.CreateAttached("Name", typeof(string), typeof(TestEffect), "", propertyChanged: OnNameChanged); public static string GetName(BindableObject view) { return (string)view.GetValue(NameProperty); } public static void SetName(BindableObject view, string value) { view.SetValue(NameProperty, value); } private static void OnNameChanged(BindableObject bindable, object oldValue, object newValue) { var view = bindable as View; if (view == null) { return; } var name = (string)newValue; view.Effects.Add(new UITestEffect()); } } class UITestEffect : RoutingEffect { public UITestEffect() : base("com.denasu.UITestEffect") { } }
次に各プラットフォーム用のEffect。
[assembly: ResolutionGroupName("company name")] [assembly: ExportEffect(typeof(App1.WPF.UITestEffect), "UITestEffect")] namespace App1.WPF { public class UITestEffect : PlatformEffect { protected override void OnAttached() { var name = TestEffect.GetName(Element); Control.SetValue(System.Windows.FrameworkElement.NameProperty, name); } protected override void OnDetached() { Control.SetValue(System.Windows.FrameworkElement.NameProperty, ""); } } }
[assembly: ResolutionGroupName("company name")] [assembly: ExportEffect(typeof(App1.UWP.UITestEffect), "UITestEffect")] namespace App1.UWP { public class UITestEffect : PlatformEffect { protected override void OnAttached() { var name = TestEffect.GetName(Element); Control.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty, name); } protected override void OnDetached() { Control.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty, ""); } } }
[assembly: ResolutionGroupName("company name")] [assembly: ExportEffect(typeof(App1.Droid.UITestEffect), "UITestEffect")] namespace App1.Droid { public class UITestEffect : PlatformEffect { protected override void OnAttached() { var name = TestEffect.GetName(Element); Control.ContentDescription = name; } protected override void OnDetached() { Control.ContentDescription = ""; } } }
XAMLではEffectを付ける。
<Entry local:TestEffect.Name="Text1" Text="{Binding TextA}" WidthRequest="100" /> <Entry local:TestEffect.Name="Text2" Text="{Binding TextB}" WidthRequest="100"/> <Label local:TestEffect.Name="Result" Text="{Binding TextC}" WidthRequest="100"/> <Button local:TestEffect.Name="Execute" Text="Button" Clicked="Button_Click" WidthRequest="100"/>
C#ではこんな感じ。各プラットフォームのセッションを作って、共通のテストを実行するようにしてみた。
[TestClass] public class UnitTest { [TestMethod] public void TestMethod1() { var session = CreateSessionUWP(); session.FindElementByAccessibilityId("Text1").Click(); session.Keyboard.PressKey("111"); session.FindElementByAccessibilityId("Text2").Click(); session.Keyboard.PressKey("222"); session.FindElementByAccessibilityId("Execute").Click(); Assert.AreEqual(session.FindElementByAccessibilityId("Result").Text , "111222"); } private WindowsDriver<WindowsElement> CreateSessionUWP() { DesiredCapabilities appCapabilities = new DesiredCapabilities(); appCapabilities.SetCapability("app", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXX!App"); return new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appCapabilities); } private WindowsDriver<WindowsElement> CreateSessionWPF() { DesiredCapabilities appCapabilities = new DesiredCapabilities(); appCapabilities.SetCapability("app", @"c:\xxx\App1.WPF.exe"); return new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appCapabilities); } private AndroidDriver<AndroidElement> CreateSessionAndroid() { DesiredCapabilities appCapabilities = new DesiredCapabilities(); appCapabilities.SetCapability(MobileCapabilityType.DeviceName, "emulator-5554"); appCapabilities.SetCapability(MobileCapabilityType.PlatformVersion, "8.1"); appCapabilities.SetCapability(AndroidMobileCapabilityType.AppPackage, "com.companyname.App1"); appCapabilities.SetCapability(MobileCapabilityType.PlatformName, "Android"); appCapabilities.SetCapability(AndroidMobileCapabilityType.AppActivity, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.MainActivity"); return new AndroidDriver<AndroidElement>(new Uri("http://127.0.0.1:4723/wd/hub"), appCapabilities); }
実行はこんな感じ。静止画じゃ分からないけど、勝手に文字が入力されてボタンが押される。
てことで、単純なUIのテストはこれで自動化できるかな。まあ、UIが崩れるとか、なんか変、っていうバグの方が多いんだけど、画面遷移とかはこれで自動化して、人が見ないと分からないようなテストにリソースを集中できれば成功かな。
そして、まだ試してないけど問題文章も自動で打てるのだろうか。そうすると不正ツールを作れてしまうかも。とりあえず打ち込み速度が遅いからよさそうだけど、設定ができたりすると厄介。
2019/03/02にWTオンライン大会「Warriors of Typing」が開かれるとのこと。運営Twitter参照。
運営者さんからは、ポート開放の手間がないWT3.5を使いたいという打診が少し前にあって、WT3.5での対戦実績がないから少し不安なものの、OKを返している。とりあえずWTサーバが落ちるとどうしようもなくなるため、1分ごとに監視して落ちてたら再起動する、という保険は打っておいた。
ちなみにWT3.5はまだ開発版。Windowsデスクトップ版ではテストは完了しているのだが、Windowsストア、Android、iOS、Macが一通りそろってから正式版にしようかと考えている。今のままだと、Mac版の人とWindows版の人がデフォルトでは対戦できなくなってしまうので。まあ、今の使われ方ではそこまで気にしなくていいだろうけど。
冬休みの研究としてウェザタイをクライアントサーバ方式にしてみた。これをそのまま使えばポート開放しなくてよくなる。ただ,全部をサーバクライアント方式にすると,サーバの通信量的にどうなんだろう,というのがあるので,直接つながらなかったときだけウェザタイサーバを使うようにすることを検討中。ちなみに通信量を測ってみたら,4人対戦で30ワード打つとだいたい送受信2.5MB。1日100回対戦があっても250MBで,全部クライアントサーバにしたところで,まあたいしたことはないのかな,とは思う。
ちなみに,以前のネットワーク構成。ホストとゲストをP2Pで接続するので,全員にポート開放が必要。元々はホストもゲストも同条件にしたかったのでこういう構成にした。
今のネットワーク構成。ホスト側にサーバを分離して,ゲストからはサーバにつなぎにいくので,ホスト側だけポート開放が必要。遅延が大きい環境だと,多少ホスト有利になる可能性がある。
で,検討中のネットワーク構成。分離していたホストをdenasuサーバへ持って行くことで完全なサーバクライアントに。
一応もう一つ選択肢があって,サーバを公開して誰でもサーバをたてられるようにする,というのもある。Linuxに.NET Core runtimeを入れて,1.5MBくらいのサーバを実行するだけで,サーバを立てるのは割とお手軽。