GameWith Developer Blog

GameWith のエンジニア、デザイナーが技術について日々発信していきます。

GameWith フロントエンド もくもく会 #9 開催しました #GameWith #TechWith #gamewith_moku2

はじめに

こんにちは。GameWithのエンジニアのtiwuです。

3月28日(木)にGameWith主催で第9回目のもくもく会を開催しました!

GameWith フロントエンド もくもく会 #9

gamewith.connpass.com

今回のテーマも前回に引き続き、僕自身が関心を高く持っているフロントエンドを採用しました。

当日は外部の参加者の方4名(内1人はインターンに参加していただいた学生さんでした!)にお越しいただきました!

f:id:tiwu:20190329134140p:plain

もくもく会は最初にお知らせ、次に自己紹介と今日のもくもく内容を発表して、もくもくし、最後に進捗発表という流れで開催しました!

僕はWeb Componentsの勉強・実装をしていました。

2時間ほどもくもくしたら本日の進捗の発表をしました!

といった様々なテーマの取り組みのもくもく会でした!

前回のもくもく会もそうでしたが、Vue.js関連の技術はとても関心が高いなと感じます。

また、Gamepad APIというAPIがブラウザに生えているのが一番の驚きでしたw

最後に

参加していただいた皆様ありがとうございました!

GameWithは、フロントエンドが大好きで、新しい技術をどんどん使っていきたいという方を大募集中! Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

またGameWithのDeveloper向けTwitterアカウントも開設しました。
もくもく会の告知やブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com

#PHPerKaigi 2019 にスポンサーとして協賛します #GameWith #TechWith

こんにちは、GameWithカンファレンスインフラ担当 加我(id:damenaragyouza)です。

この度、PHPerKaigi 2019にダイヤモンドスポンサーとして協賛することになりました。
そして弊社のエンジニアが PHPでJVMに入門する というインパクトある内容で登壇します。

参加者のみなさまにはデザイナーが頑張って作ってくれた渾身のノベルティを用意しておりますのでお楽しみに。

当日はエンジニア・デザイナーが複数名参加しますので、トークの感想やノベルティの感想など、わいわい交流できることを楽しみにしております。(ちなみに私は撮影スタッフをしております)

イベントの詳細につきましては公式サイトを参照下さい。

phperkaigi.jp

PHPerチャレンジ

さて、今回のPHPerKaigiでは PHPerチャレンジ という企画があります。
どういうものなのか公式ブログから内容を抜粋してみます。

PHPerチャレンジとは

PHPerチャレンジは会場内外に隠された「PHPerトークン」を探しだし、イベントサイトに入力して得られたスコアを競う企画です。 
PHPerトークンは「記号の# + 任意の文字列」の形をしています。
PHPerトークンを見つけたら、現地でお渡しする名札の裏面のQRコードからPHPerチャレンジサイトを開いて入力してください。スコアが加算されます。 PHPerトークンはチャレンジサイトに早く入力するほど高得点です!PHPerトークンを見つけたらすぐ入力しましょう!

最終日のクロージングで獲得スコアに応じて表彰を行います。お楽しみに!

セキュリティ系でよく見るCTF(Capture The Flag)を模した形の企画でしょうか。

www.publickey1.jp

PHPerKaigi 2019公式サイト、スポンサーさまサイト、その他、PHPerKaigi 2019に関連するサイトがその対象です。
との事なので、さきほどブログのどこかにトークンを埋め込みました!

頑張って見つけてみて下さい🙏

さいごに

GameWithではエンジニアを募集中です。

スポンサー枠があるから登壇してみなよと囁いてくる人がいたり、トーク応募のプロポーザルを一緒に考えてくれる人がいたりと、「登壇してみたいけど、でも・・・」という人でもみんながフォローしてくれる良い環境だと思います。
興味のある方は是非、話を聞きに来てみてください。そしてみんなで一緒にテックカンファレンスを盛り上げていきましょう!
www.wantedly.com

GameWith Developer BlogとGameWith Developer Twitterのロゴリニューアルしました! #GameWith #TechWith

はじめに

はじめまして、GameWithでデザイナーをしている @Fuki です!

突然ですがこのブログのロゴ(ヘッダー)が3月中旬にリニューアルされたのはお気づきでしょうか?

ちょっとおしゃれにしてみたんですが…..。どれくらいの方が気づいてくれてたでしょうか。

今回このロゴのデザインを担当させていただいたので、決定までの流れやデザインフローについてお伝えできたらと思います!

リニューアルのきっかけ

さて、以前のロゴはこんな感じのデザインでした↓

f:id:tiwu:20190325182004p:plain

2年間頑張ってくれたこのデザイン、実はこんな問題点がありました。

  • 当時のデザイン担当が速度優先でぱぱっと作ってくれたものをずっと使用していた
  • 「ゲームウィズ」のカタカナ表記のみしか入っていない(正式な表記じゃないんです…。)

また、GameWithというブランドをさらに誠実に、信頼感あるものにしていこうということで ロゴの規定を強化しているため、

  • サービスを指しているわけではないのに、ロゴマークを単体で使っている
  • GameWithのロゴタイプが付随していない

といったガイドライン抵触問題も新たに浮上しました。

ブログの更新頻度も高まり、Twitterも開設、これからさらに開発部の露出を頑張っていこう!という時期。

そろそろしっかり見せていきましょう!という訳で、リニューアルに着手することになりました。

リニューアルの流れ

まず呼び名を決める

「そもそも我々エンジニア、デザイナーをまとめてどう呼んだらいいものか….?」

部署としてはサービス開発部という名称なのですが、これはあくまで社内での呼称。

社外の方には聞き慣れないし、より一般的な呼称にするべきと考えておりました。

(それに部署名をまんま使うより、少しカッコつけたいじゃないですか….!)

今まではなんとなく「エンジニアリングブログ」としていたのですが、メンバーが増えた今再考したほうがいいかも。

ということで以下の3つの候補から、実際に部署内で多数決を取って決めることに。

f:id:tiwu:20190325175803p:plain

f:id:tiwu:20190325175830p:plain

f:id:tiwu:20190325175816p:plain

結果、僅差で「Developer / Dev」に決定しました!

ここのニュアンスはデザイナー1人で見極めるのが難しかったため、少し手間でも聞いてよかった〜と感じました。

また、今回は開発部全体の看板を作るお仕事なので、「何も知らないうちに呼び方とかデザインとか決まっちゃってる…。」となるのは寂しいので避けたいと思っていました。

多少大げさと思われても、みんなを巻き込んで参加していただくことに意義があると感じました!

ヒアリング

名前が決まったところでデザイン作業開始!

まずはイメージボードを作成しました。

まずは資料を見ながらブログ担当のエンジニアさんとイメージの擦り合わせをします。

要望をヒアリング→pinterestでマッチした作例を探す→もっとこう、これは避けたい…→さらに資料を探す…の繰り返しです。

デザイン作業の最初のステップで要望を言葉だけで聞いて承知しました〜一旦持ち帰って資料なげますね〜というフローは多いかと思いますが、 後々すっごく面倒になることが多いですよね。

思ってたのと違うんですけど!とか、どれが正解なのかわかんない…。とか言われてしまって…。私も多々失敗しております。

担当の方と面と向かってお話できるチャンスがあるなら、絶対に画像を漁りながら喋りまくるのが良いと思います。「これ?それともこれ?」

とその場で相手の脳内イメージを引き出しつつ、その場で要望を満たすためのデザイン条件などの補足もいれます。

この作業を挟むとブレが少ない中でバリエーションが作成でき、作業時間も大幅に短縮されるのですごく大事だと思っています。

今回の担当さんからの要望は以下のものでした。

  • 会社の一組織として露出するため、あまりにもポップすぎるのは避けたい
  • シュッとしていて、余計な装飾がない
  • 開発部っぽいワンポイントはあってもいいかも?
  • GameWithのロゴの横に置いておかしくないようにしたい

この要望を聞きながら集めた画像を1枚にまとめます。

作成したイメージボードからあまり離れないようにバリエーションを何個か作っていきます。

デザイン作業

フォントをひたすらバリエーション出して…。

f:id:tiwu:20190325180055p:plain

イメージに合うフォントを使いつつ、より綺麗な形の文字を別のところから拝借したりして…。

f:id:tiwu:20190325182136p:plain

要望よりあえてめちゃくちゃ遊んだいわゆる「捨て案」的なものも用意して…(よくまさかのこっちが通っちゃうデザイナーあるある)

f:id:tiwu:20190325182149p:plain

デザインに詳しくない人でも良し悪しが判断できるよう、デザイン意図やニュアンスを書いた補足文をつけて….。

3案完成!こちらも最終決定は部署内で多数決します!

f:id:tiwu:20190325180142p:plain

ロゴ決定!

結果…。思惑通り(?)こちらの案に決定!

f:id:tiwu:20190325180217p:plain

濃い青を主体とした落ち着いた印象のフォントに、スラブセリフのような装飾をつけてシンプルながらオリジナリティが出るようにしました。

ワンポイントにコーポレートカラーを使って「o」の文字を電源マークにしました。単純明快に機械らしさを出せたかと思います。

各文字は角をほんの少しだけ丸めて、GameWithロゴと馴染むよう調整しました。

バランスの良いロゴができたと….思います….!!

もちろん他の案が通っても悔いのないところまで仕上げたつもりです!が、やはり当初からこういうデザインが一番開発部らしいよね、 と打ち合わせていた案になってホッとしました。使い倒すぞ!

各SNS用にアレンジ

ブログトップやTwitterに使うため、装飾を加えた画像を納品しました。

GameWithといえばゲームモチーフ…。も考えましたが、これらのメディアでは開発者の方々や技術に関する情報が主役。

色々な人の色々な情報発信がこのメディアを通して行われているぞ!ということを一目でわかってもらうため、カラフルな仕事中の人物イラストを配置しました。

f:id:tiwu:20190325180520p:plain

納品完了!実作業時間は間はあったものの、1日3時間ほど使わせてもらって納品まで約6営業日ほどだったと思います。

周りのご協力のおかげで大変スピーディかつ妥協のない仕事運びができたと思います!

最後に

今回のロゴデザインが滞りなく進んだのは、やはり早い段階から多くの人を巻き込めたからだと思います。

普段デザインをしているエリアは、隣もデザイナーさんだったりして絵を見せただけでこれがよい、悪いと判断できる方でまとまっていることが多いです。

結果めちゃ早フィードバックをいただけてとても助かっているのですが、それはデザイン提案とはまた違うんだな…。と改めて実感しました。

今回は最初から「部署の皆さんの多数決でいきましょう!」と担当の方に提案いただいたおかげで、「このデザインにはどんな意図を持たせて、どういった路線で提案しよう」 という提案前提の考え方でバリエーション展開を考えたり、意図をわかりやすく説明できるように頭の中で考えながら作業することができました。

私はデザイナーとしてはまだまだ駆け出しなのですが、最近は「なんとなく手先でデザインが出来るようになっちゃったな…」と思っていた矢先のお仕事だったので、 また気を引き締め直すことができ、よい経験となりました!

これからもしっかりと筋の通った、かつおしゃれなものをバンバン出してみんなのテンションを上げていきたいと思います!

今後はエンジニアさんだけではなく、GameWithデザイナーにもご注目!よろしくお願いいたします!

GameWithは一緒に働く仲間を大募集中! Wantedly でもよいので是非お気軽にお声がけください!

www.wantedly.com

またGameWithのDeveloper向けTwitterアカウントも開設しました。

もくもく会の告知やブログの更新情報などを発信するので良かったらフォロー宜しくお願いします!

twitter.com

GameWith で初のエンジニアインターンを実施しました。 #GameWith #TechWith

エンジニア兼インターン総合実施責任者のめもりー (@m3m0r7) です。 GameWith では 2019/03/7(木) から 2019/03/20(水) にかけて、サービス開発部主催の初のエンジニアインターンシップを行いました。 本インターンには想像以上に多くの方からご応募があり、本当にありがとうございました。

この記事ではどんなインターンシップだったのか、インターンシップを実施するまでの裏話的なのを書きたいと思っています。

どんなインターンシップだったのか

初日から開発まで

本インターンシップは2週間(営業日換算10日)という期間で1つのサービスをチームで作っていくものでした。本インターンの趣旨は「チーム開発」としており、 チーム対抗ではなく、そのチームのリソースや動きなどを自分たちで意思決定して進んでいってもらうものでした。

タイムスケジュールとしては、1日目はオリエンテーション、2日目からは実際に開発と開発の時間を長めに取れるような構成にしました。 下記は実際に今回のインターンシップで使用されたタイムスケジュールです。

f:id:m3m0r7:20190322122511j:plain

初日はオリエンテーションを行い、メンター各自の自己紹介を行いました。 f:id:m3m0r7:20190322122948j:plain

開発のお題は予め GameWith で3つほど用意し、インターン生達にどのお題でやりたいかを話し合って頂いて、お題を決定しました。 今回のお題は「ゲームでマッチングするサービス」となり、2つのチームに分かれてチームの運用方針から Git の使用方法、技術選定などを考えていただいて 実際に開発していくものとなりました。

開発に入る前にチーム名を決めていただき、それぞれ「宇治抹茶チーム」、「2 / 3 メガネチーム」となりました。 最終的にはチーム名に愛着があったようで良かったです!

f:id:m3m0r7:20190322121810j:plain

チーム責任者のもとで、インターン生のみなさんが白熱した議論をしていて、私も議論に参加したいぐぬぬ…と我慢した覚えがあります。

また、今回のインターンでは1日の終りに メンターとインターン生が対面で話す 1 on 1 の時間を毎日設けました。 インターン生が抱えている課題を一緒に解決していって、このインターンシップをより良いものにしたいという思いがあったため、設けました。 また、 1 on 1 実施後はメンター同士で集まり、課題を収集し解決していく方針を決定していました。 初めての実施ということもあり、メンター自身が困っていることがないかどうかもその場で洗い出して、解決していくという方針になっていました。

実際の開発

インターン生の実際の開発では AWS の EC2 を GameWith が提供したり、 Firebase を使ってもらうなど実際の業務に近いかたちの環境化で開発していただけたのではないかなと思っています。 f:id:m3m0r7:20190322124045j:plain

自発的に S3 を使いたい、 Firebase を使いたいという声があがって、改めて学生は優秀だなと実感しました。 GameWith はPHPをメインとして扱っている会社であるため、 両チームともに PHPのウェブフレームワークである Laravel や、フロントエンドに関しては Vue, Reactなどモダンなものを選んでいらっしゃいました。

いろいろとつまづきポイントがあったり、メンターと一緒になんで動かないんだろうと考える時間を思い出すととても楽しかったという記憶があります。

中間発表

中間発表では、サービス開発部の島付近で各チームの進捗と開発しているものを発表していただきました。インターン生たちが緊張している中ではあるものの、中間発表も各チームのいい味が出せていて良かったのではないかなって思ってます。

(すみません、写真を取り忘れました…!)

最終発表

最終発表では中間発表と同じ形で発表していただきました。中間発表は1チーム15分でしたが、最終発表では1チーム30分の時間を取っていただきました。 泣いても笑っても最後という段階で、緊迫している中、サービス開発部からは盛大な拍手があり、無事終了しました。

f:id:m3m0r7:20190322125655j:plain

f:id:m3m0r7:20190322125633j:plain

インターンシップの実施を通して

最終的にアンケートを取って、インターン生たちからはとても良かった、有意義だった、参加して本当に良かった、また参加してみたいなどの嬉しいお言葉をいただきました。 GameWith のエンジニアインターンは初めてという中で、メンターの皆さんも成功させたいという一心で動いていたと思うので、成功したのではないかなと思っています。

f:id:m3m0r7:20190322125721j:plain

インターンシップを実施するまで

インターンシップの企画

開発部で初のインターンシップを行うという企画自体は2018年の8月から9月にかけて行われました。 部長、マネージャーと話を進めながら、他社のインターンを参考にしつつ企画を進めていきました。 例えば、インターンシップを行う目的はなにか、実施することによって会社が得られるものはなにか、何人採用するのか、契約形態はどうするのか、時給はどうするのか etc... いろいろと詰めていてあっという間に年末に近づき、そろそろ募集文を出さないとヤバイ、ということで募集文の準備をしていました。

片一方で

片一方で、インターンシップを一緒に実施してくれる有志を募りました。 f:id:m3m0r7:20190322131650p:plain

合計で9人ほど集まりました。 最初にキックオフを行い、どういうことをインターンシップで行うのか、タイムスケジュールはどうするのかなどを話し合って詰めていました。 また、採用基準をどうするのか話し合って決定しました。

面接 / 面談について

集まっていただいた9人から、面接/面談を担当する方を決めて、多くの学生さんたちとお話させていただきました。 今回はメンターの人数の問題もあり、1次面接のみという形で進めさせていただきました。

メンターの役割

本インターンシップでは4つのロールを定め、それぞれの役割にメンターが専念して貰う形にしました。 定めることにより、自分たちがどういった行動をすればよいのかが明確になるためです。

f:id:m3m0r7:20190322132713p:plain

実施前に期待値の確認を行う

インターンシップ実施の前にインターン生にアンケートをお送りし、GameWith のインターンシップに期待していることを予め知ることにより、 期待値の調整や、期待していることに応えられたのではないかなと思っています。

多くの部署を巻き込んだ

今回のインターン実施では多くの部署を巻き込みました。それでも各部署の方々は快くサポートしてくださったので、今回のインターンが成功したのだと思っています。

インターンを実施時に出てきた課題

主にタイムスケジュールに関連した課題が多いかなと本インターンでは感じました。 タイムスケジュールの調整が間に合わず、大枠しか確定していない状態で面接を開始してしまったのが今でも課題だったなと思っています。 インターンの実施については、事前にどれだけ準備・他部署と連携するかが大切だと改めて実感しました。 タイムスケジュールの組み方も初めてだったということもあり、オリエンテーションはオリエンテーションで固めすぎていましたが、分散させるべきだったなと反省しています。 メンターやチーム責任者がインターンをどう進めていくべき・どういう存在であるべきか、もう少しディスカッションする時間があっても良かったかなとも感じました。 今回は私の事前準備の至らなさで、ディスカッションする時間がほぼなく、それでもアドリブでインターンを成功させようと尽力してくださった皆様には感謝しきれません。

最後に

いかがでしたでしょうか、今回のインターンシップを実施するまでから実施してみてまでの一連の流れを書かせていただきました。 GameWith ではこのような企画などもしているので、興味があればぜひご応募お待ちしております。

www.wantedly.com

LINEチャットボットをリリースして得た知見 #GameWith #TechWith

こんにちは、iOSエンジニアのchuymasterです!最近バイオハザード RE:2をようやく始めて、悲鳴を上げながらストーリー攻略を目指しています。

2月下旬、GameWithの初めてのチャットボットをリリースしました!今回は、チャットボット作成で得た知見を共有したいと思います。技術構成も記載しますが、かなりプロダクト寄りの内容になります。

f:id:gwchai:20190311183737p:plain:w300
マルチ募集チャットボット

どんなチャットボット?

モンストのマルチプレイの仲間募集を手伝ってくれる可愛らしいLINEのチャットボットです。「マルチ募集チャットボット」と呼んでいます。何ができるか?どうやって使うかはこちら↓

gamewith.jp

チャットボットの検証と仮実装は昨年末から始まっていて、こちらの記事で詳しく説明したので、よかったらどうぞ合わせて読んでください。

tech.gamewith.co.jp

プロジェクトの前提

本当にユーザーがチャットボットを使ってくれるかどうかの確信がないため、今回は最小限のリソースでプロダクトのリリースを最優先した「実験プロジェクト」になります。

「マルチ募集チャットボット」はあくまでもチャットボットの価値を検証するためのプロジェクトという前提で進めています。

開発スケジュール

f:id:gwchai:20190308141552p:plain
当初のガントチャート

僕がiOSエンジニアの掛け持ちでチャットボットを作っているので、半分ぐらいの時間を使う感覚で開発期間を1ヶ月程度設けました。開発者は、Androidアプリ開発以外は僕一人です。

1月末公開の予定でしたが、iOSアプリの開発が押していて優先対応したので、結果的に2月22日が公開日となりました。

技術構成

バックエンド

LINE Messaging APIのやりとりと、アプリ向けAPIはFirebase Functionsを使っています。

サーバーレスなので、インフラの心配をしなくて良い点と、iOS開発者としてFirebaseに馴染みがある点が採用の理由です。

フロントエンド

Firebase Hostingを使っています。アプリへのリダイレクトページと、画像の提供で使っています。本当は画像はStorageを使うべきですが、量が少ないのでHostingでとりあえずやりました。

データベース

Realtime Databaseを使っています。Cloud Firestoreは開発しているとき、データの1件取得に2秒かかることが多くて許容範囲外だったので、その問題がないRealtime Databaseを採用しました。Cloud Firestoreは今はBetaが外れたので、いずれ移行したいと考えています。

上記で分かるように、チャットボットを支えるのはすべてFirebaseの機能です。Firebaseだけで本当にいろいろなことができます。Firebaseの他の機能の説明は、弊社のエンジニアが詳しく書いてあるので、よかったらお読みください。

tech.gamewith.co.jp

言語

Firebase Functionsの開発はTypeScriptを使っています。Functionsの開発言語はJavaScriptも選べます。ですが、SwiftでコーディングしているiOSエンジニアとして、型がないことは死活問題なので、型があるTypeScriptを選びました。

SwiftとTypeScriptは意外と似ていて書きやすかったです。機会があればこの2つの言語を比べたいと思います。

クライアントアプリ

クライアントアプリはGameWith本体のiOS/Androidアプリに、チャットボットから送るURLスキーム情報を受け取って、マルチ募集を自動で開始する処理を追加しました。

学んだこと

ここからが、プロダクト開発を通して得た知見です。チャットボットの成功の秘訣!とまではいかないですが、失敗しないための3つの知見を紹介します。

1. チャットボットだからこそ「ものすごく便利に」できることを考えよう

チャットボットは対話UIを通したアプリだと僕は思っています。アプリと同様、価値がないと判断されるとすぐ削除=ブロックされてしまうので、チャットボットだからこそ「ものすごく便利に」なる体験を提供しないといけません。

幸い、モンストユーザーの課題は明確です。マルチで遊ぶ仲間を募集するためには、モンストから一度募集メッセージをLINEに送信して、GameWithアプリにコピペしないといけないことです。

コピペの手間は大きくないかもしれませんが、ヘビーユーザーは1人1日、20回以上募集をかけているので、かなりストレスに感じるはずです。

マルチ募集チャットボットなら、そのものすごい手間がなくなるので、使う価値はあります。

リリース後、マルチ募集をかけているアプリユーザーの2割以上がチャットボットを使っているので、かなり多く使っていただいていると思います。

2.チャットボットのイメージを可視化してメンバーに伝えよう

チャットボットは画面がないので、サービスのイメージがパッと分かる一枚資料が作れません。

そこで、プロジェクト関係者にイメージ共有するため、公式ツールのLINE Bot Designerを使いました。

f:id:gwchai:20190311130042p:plain
LINE Bot Designerの実際の画面

想定したユースケースを全部洗い出して、各ケースの会話シミュレーションを作りました。これが設計書になっていて、プロジェクト関係者に説明するときは、ユーザーになったつもりで、各ケースの会話の順番を追いながら説明して認識を合わせることができました。

モンスト攻略担当者がこれを見て、会話の内容を指摘してくれたし、デザイナーが直接これを使って、色の調整などをしてくれたので、とても使いやすいツールだと思います。

3. キャラクターを決めて、ボットに命を吹き込もう

マルチ募集のチャットボットは、「乃灯あろん(のとあろん)」というキャラクターで返事しています。あろんちゃんは開発部のデザイナーが心をこめて描いた(非公式)キャラクターです。

f:id:gwchai:20190311185949p:plain
LINEのチャットアイコン&ホームで登場する「あろんちゃん」

今まで、活躍するところが少なくて、GameWithアプリのチュートリアルぐらいでしか登場する場面がないですが、今回はチャットボットで登場してもらうことにしました。

そこで必要になるのがセリフですが、最初のリリースでは、「機能的」なセリフしか用意していなくて、モンストの募集メッセージ以外の言葉を送ると「ごめんなさい」としか返事できませんでした。

開発部内でもこれは切ないという声が上がったので、早速あろんちゃんの生みの親に、いくつかのキーワードに反応するセリフを作ってもらいました。そして実装したところ、ツイッターでちらほら画面のキャプチャをして拡散してくれるユーザーがいて、だいぶ盛り上がりました。

f:id:gwchai:20190311182942p:plain:w300
セリフのおかげで可愛らしくなりました

チャットサービスを使うと、ウェブと違ってユーザーは人と話す感覚になるので、愛用されるチャットボットになるには、こうした人間らしさが必要だと気付きました。

ちなみに「乃灯あろん」の名前は社内公募で決めました。名前の由来は英語のNot Aloneとかけて、マルチでゲームをするユーザーの手助けができるよう「あなた一人じゃない」「私がいます」という意味を込めています!

今後の展開

今は各種プロモーションを使ってマルチ募集チャットボットの認知度を上げています。

一定数のユーザーに使っていただけて、アプリのユーザー増加に十分貢献できると判断できれば、本格的にチャットボット開発に取り組みたいと考えています。

その際、チャットボットだからこそものすごく便利にできることって何だろう?を真剣に考えて、ユースケースを設計し直す必要があるので、さらに大きな挑戦になりそうです!

GameWithではチャットボットに限らず、様々な新規事業に挑戦しています。我も新規開発をしてみたい!という志を持つ方をGameWith開発部が募集中です!

興味があって話を聞いて見たいなぁと思った方は是非Wantedlyで会いに来てください! www.wantedly.com

エンジニア公式ツイッターもはじめてます。フォローをよろしくお願いします! twitter.com

ExoPlayerを使ってAndroidアプリに動画を入れた話 #GameWith #TechWith

はじめまして、GameWithでAndroidエンジニアをしているgiです。 iOSの攻略動画に続き、Androidもv2.1.0で攻略動画を見られるようになりました。

前回kyamさんが書いたiOSの記事:

tech.gamewith.co.jp

今回はExoPlayer(v2.9.6)の使い方について話をします。

目次

簡単の紹介

公式サイト: https://google.github.io/ExoPlayer/
Source code: https://github.com/google/ExoPlayer
ExoPlayerはGoogleが開発したアプリケーションレベルのMediaPlayerです。Libraryとして扱うため、AndroidのSource codeにはありません。

メリットとデメリット

メリット

  • DASH、SmoothStreamingなどMediaPlayerがサポートされてない動画もサポートしています
  • カスタマイズは簡単
  • アプリと一緒にアップデートできます

デメリット

  • Libraryですので、アプリのサイズが増えます
  • Android 4.1からの MediaCodec API に依存しているため、4.1以前は使えません

使い方

Gradle設定

GoogleとJcenterのリポジトリが必要です

    repositories {
        google()
        jcenter()
    }

dependencies

  // core、必須のdependency、ほかのdependencyは全部オプショナルです
  implementation 'com.google.android.exoplayer:exoplayer-core:2.9.6'
  // hlsをサポートしたいときのdependency
  implementation 'com.google.android.exoplayer:exoplayer-hls:2.9.6'
  // smoothstreamingをサポートしたいときのdependency
  implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.9.6'
  // dashをサポートしたいときのdependency
  implementation 'com.google.android.exoplayer:exoplayer-dash:2.9.6'
  // デフォルトのUIを入れたdependency、自分でUIを書くのもできますが、これがあると便利です
  implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.6'

ほかにrtmp、flacなどのextensionもあります:https://github.com/google/ExoPlayer/tree/release-v2/extensions/

Java 8の設定

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

ExoPlayer v2.9.0以上はJava 8の設定が必要です。

playerのインスタンスを作る

  val player = ExoPlayerFactory.newSimpleInstance(context)

newSimpleInstanceメソッドが複数あって、ContextRenderersFactoryTrackSelectorLoadControlなどいろいろなカスタマイズができます。一番簡単なのはContextだけ設定して、ほかは全部デフォルトにするこのメソッドです。

playerをViewに設置する

exoplayer-uiを使っている場合

直接中のPlayerViewを使うことができます:

  playerView.setPlayer(player)

exoplayer-uiを使ってない場合

自分が書いたViewとplayerの連携を取る必要があります。

動画Url(mp4)を使ってMediaSourceを作る

  // 1つの動画
  val dataSourceFactory = DefaultDataSourceFactory(context, Util.getUserAgent(context, context.packageName))
  val mediaSource = ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(url))

  // 1つの動画を10回ループする
  val mediaSource = ...
  val loopingMediaSource = LoopingMediaSource(mediaSource, 10)

  // 3つの動画を連続で再生する
  val mediaSource1 = ...
  val mediaSource2 = ...
  val mediaSource3 = ...
  val concatenatingMediaSource = ConcatenatingMediaSource(mediaSource1, mediaSource2, mediaSource3)

hls、smoothstreaming、dashが必要なとき、それぞれのHlsMediaSourceSsMediaSourceDashMediaSourceを使う必要があります。

MediaSourceとplayerを組み合わせて動画を再生する

  player.prepare(mediaSource)

EventListenerを使ってplayerの状態変化を取る

  player.addListener(object : Player.EventListener{
    // タイムラインが変わった、再生が始まった、再生が止まった、再生がエラーになったなどの情報はここで取れます
  })

音量の設定

  player.setVolume(audioVolume)

audioVolumeは0〜1のfloat、0は音なし、1は最大。この設定は、あくまでplayerの音量設定です。デバイスの音量をOFFにしたら、setVolumeで最大に設定しても、音が出ません。

動画のplayとpause

  // play
  player.setPlayWhenReady(true)

  // pause
  player.setPlayWhenReady(false)

動画画面を閉じるときの処理

  player.release()
  player = null

UIのカスタマイズ

exoplayer-uiを使っている場合

  • Libraryにあるexo_simple_player_view.xmlを参照して、自分のUIをカスタマイズする、exo_simple_player_view.xmlのコード:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">

  <com.google.android.exoplayer2.ui.AspectRatioFrameLayout android:id="@id/exo_content_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_gravity="center">

    <!-- Video surface will be inserted as the first child of the content frame. -->

    <View android:id="@id/exo_shutter"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black"/>

    <ImageView android:id="@id/exo_artwork"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"/>

    <com.google.android.exoplayer2.ui.SubtitleView android:id="@id/exo_subtitles"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ProgressBar android:id="@id/exo_buffering"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:layout_gravity="center"/>

    <TextView android:id="@id/exo_error_message"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:background="@color/exo_error_message_background_color"
        android:padding="16dp"/>

  </com.google.android.exoplayer2.ui.AspectRatioFrameLayout>

  <FrameLayout android:id="@id/exo_ad_overlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

  <FrameLayout android:id="@id/exo_overlay"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

  <View android:id="@id/exo_controller_placeholder"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

</merge>

動画の場合、exo_content_frameが必須です。再生している動画を表示するTexureView/SurfaceViewがその中に入るためです。ほかのViewは全部なくっても問題ないです。別のIDが付いたViewを追加しても問題ないです。ただしその場合、そのViewを自分で制御しなければならないです。 コントローラーが欲しい場合、exo_controller_placeholderあるいはexo_controllerが必要です。

  • コントローラーをカスタマイズする場合、exo_playback_control_view.xmlを参照して、自分のUIをカタマイズする。

  • PlayerViewplayer_layout_idcontroller_layout_idを設定する

    <com.google.android.exoplayer2.ui.PlayerView
      android:id="@+id/player_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:player_layout_id="@layout/my_player_view"
      app:controller_layout_id="my_controller_view"
      />

exoplayer-uiを使ってない場合

すべてのUIを自分で作るため、特別な設定は必要ないです。

まとめ

以上がExoPlayerの簡単な使い方です。あまり複雑なものが必要ないなら、結構使いやすいLibraryです。また、Github上のdemoにはいろいろな複雑な機能を実装しています。とても勉強になります。

終わりに

GameWithアプリチームでは一緒にアプリをよくしていく仲間を募集中です! 興味がありましたら以下からご連絡をいただけるとありがたいです。

www.wantedly.com

毎年旧バージョンのiOSサポート打ち切り交渉するのが大変なので、iOSアプリ サポートOSバージョンルールを作った #GameWith #TechWith

こんばんは、ApexLegendsで物資調達中に崖から転落死した @peka3 です。

iOSは毎年メジャーバージョンアップが行われますね!

ずっと古いバージョンもサポートできればいいのですが、そうすると開発効率が落ちていくので、サポートバージョンを打ち切ることも大事だったりします。

そういうときはエンジニアとプロダクトオーナー間で交渉して、じゃあこのバージョンまではサポートを終了しましょう、となったりならなかったりします。

これが毎年の作業として入ってくるチームも多いのではないでしょうか!?

GameWithアプリでも先日iOS10のサポートを終了しました。

その際に「iOSアプリ サポートOSバージョンルール」を設け、今後はこのルールに沿いますということでプロダクトオーナーと合意を取ることにしました。

なぜ iOSアプリ サポートOSバージョンルール を決めたのか?

毎年iOS Xのサポートを打ち切るとどういうメリットがあって…などをまとめるのは非効率です。

そもそもサポートOSのバージョンを上げることのメリットはほとんど

  • 新機能が使えて開発効率や開発の幅が広がる
  • テストにかかる工数が削減できる

この2点に集約できるので毎回洗い出すほどではないと考えました。

よって、考えることを削減したい、コミュニケーションコストを削減したい、という目的でルールを決めました。

テスト工数削減について

ほとんどの開発において、各バージョンで動作確認するので、たとえばiOSの場合、i0S10, 11, 12 をサポートしようとすると、テストは3必要。

これが直2バージョンのみのサポートになれば、 iOS11, 12 だけでよくなり、テスト工数は 2/3 になります。

ものすごく単純計算で出しましたが、古いバージョンを打ち切ったらテスト工数が増えてしまう、ということはないでしょう。

古いOSではセキュリティリスクがある

iOSは基本的に最新のメジャーバージョンにしかセキュリティパッチが来ないので、iOS12が最新なら12未満を使ってるだけで、すでにセキュリティリスクがある状態で利用していることになります。

サポートOSバージョンを上げたとしてもサポート対象外のOSで使えないわけではない

打ち切られたOSであってもすぐに使えなくなるということはなく、AppStoreで対応していた最終版のアプリをDLもできます。

よって、サポートを打ち切られたバージョンの利用者が突如離脱につながる、ということはありません。


 

……前提のお話として、まずここまでプロダクトオーナーと認識を合わせました。

ここから具体的にどのラインを割ったらサポートを打ち切るかの交渉になるのですが、GameWithアプリでは以下のようにしました。

   

サポート打ち切りライン

iOS10はシェア3%を切ってからこの2ヶ月、2.5%〜2%前後で推移している。

バージョンアップに興味がない、したくない一部のユーザがずっと使い続けている状態であり、これ以下にはほとんど下がらないのでは?と推測できる。

よって今後も該当OSバージョンのシェアが3%未満 であればサポートを打ち切る。

……として、上記の内容でプロダクトオーナーと合意しました。

コミュニケーションコスト削減目的でもあるので、この数値を割ったらまずサポート打ち切る前提で話を進めることになります。

 

ユーザに告知する

サポートバージョン打ち切りはユーザの皆様にも理解していただかなくてはいけないので、きっちり告知をするところまで含めて行います。

gamewith.jp

   

まとめ

GameWithアプリではiOS10はこのようにしてサポート終了としました。

今後は交渉は特にせず、サポート終了をすることの確認と、ユーザへの告知記事作成だけで行ける想定です。

他のアプリでの交渉事例、シェア何%で打ち切るのかなども知りたいです!

もしよかったらコメントいただけると嬉しいです。


GameWithアプリチームでは一緒にアプリをよくしていく仲間を募集中です! 興味がありましたら以下からご連絡をいただけるとありがたいです。 www.wantedly.com

エンジニア公式ツイッターもはじめてます twitter.com