GitHubのプルリクエストからリリースノートをさっさと作る話

はじめに

ソーシャルゲーム事業部のこみやです。昼はソーシャルゲームのUIを作ったりAmazonで箱買いしたお菓子を食べたり昼寝したりしています。(夜は寝てます)
これはカヤックUnityアドベントカレンダー2018の3日目の記事です。

早速Unityとあんまり関係なくて恐縮ですが、今日は私のチームでのGitHubのプルリクエスト(以下:PR)の活用法について書きます!

概要

私が所属している開発中のプロジェクトでは現在、だいたい週に2回ほどチーム内や協業先にテストプレイしてもらうためのビルドを作っているんですが、その時に変更内容を列挙したリリースノートのようなもの(以下:ノート)を添えています。今回はそのノートを手間をかけずに作るために行った取り組みの話です。

BEFORE:旧石器時代のノート作成

半年ほど前まではビルドの際に、ノート職人(Unityエンジニア)がウェブブラウザでGitHubを開き、マージされたPR(base:<ビルドのブランチ> is:mergedで検索)を1ページずつテキストエディタにコピペして、経験と勘でそれらを選別・分類したあと、エンジニア以外にも分かる文章に直していました。これはとても創造性が高く、皆に尊敬される仕事であったことに疑う余地はありませんが、

  • 時間がかかりすぎる
  • 悲しい気持ちになる

という問題を抱えていました。

PRタイトルはちゃんと文章にしてもらうようにした

「◯◯を◯◯しました」という形式で書くことをルールにしました。そんなの当たり前じゃないかと思われる方もいるかもしれませんが、以前の私のチームには体言止めや主語/述語が無いPRタイトルが多くありました。ちなみに丁寧語なのは、協業先に渡す時に書き直す手間が省けるからです。

ただチームに外国人のエンジニアが多いこともあり、どうしても意味がよくわからないタイトルのPRもぽつぽつ出てきます。そういうのを見かけたときはSlackで本人にメンションを付けて「〜〜〜みたいなタイトルだと良かったと思います!」というようなことを言う地道な活動もしています。

f:id:moyika:20181130154411j:plainf:id:moyika:20181130154414j:plain

PRタイトルにつけるプレフィックスを刷新した

やはり人間が勘でPRを振り分けるのは疲れるし、ミスも多かったのでプレフィックスで振り分けられるようにしました。

昔のPRプレフィックス

以下はあんまり上手く機能していなかった昔のPRプレフィックス一覧です。(当時のCONTRIBUTING.md 原文ママ)

プレフィックス 使いどころ
BUGFIX 不具合の修正
FEATURE 新しい機能、機能の変更
IMPROVEMENT 機能追加でもバグ修正でもない変更
DO_NOT_MERGE マージしてはいけないプルリク。主に実機確認でビルドを作りたい場合に使う〔補足:PRにコメントすることでビルドを始める仕組みを使っているため〕
DESIGN デザインなどのリソースファイルの追加、変更

これらのプレフィックスはPRのカテゴライズに使うにはあまりにもざっくりしすぎていました。また、FEATUREとIMPROVEMENTの境界が割と謎なため、結局大半のPRがIMPROVEMENTになっていたという問題もありました。

新しいPRプレフィックス

何の捻りもないですがとにかくプレフィックスを細分化しました。前半と後半の2つの単語を組み合わせてプレフィックスを決めるようにした感じです。

参考ばかりにほぼフル(プロジェクト固有のプレフィックス・用語は省きました)で載せておきますが、あまり読む意味はないです。

普通のPR

プレフィックス前半 使いどころ
IN: インゲームに関わるPR。
IN-AI: AIのみの変更のPR。
IN-STAGE: ステージのみの変更のPR。
OUT: アウトゲームに関するPR。
IN&OUT: インゲーム・アウトゲーム両方に関わるPR。
TOOL: Unityエディタ拡張(AIエディタ等)に関わるPR。ビルドには全く影響しないもの。
DEBUG: デバッグ機能(デバッグボタン等)に関わるPR。リリースビルドには全く影響しないもの。

プレフィックス後半 使いどころ
NEW 一連の新規機能実装。直ちにビルドで確認できるとは限らない。実装が複数PRに渡る場合は全部これにする。
CHANGE 既存機能の仕様変更等に対応するための変更。
ENHANCE 既存の要素の表現(ビジュアル・サウンド)の改良。主にパーツ単位で、他の要素には直ちに影響しないもの。
REFACTOR リファクタリング。基本的にビルドには何の変化も与えず、内部の処理やシーン構造をいい感じに綺麗にしたもの。
TUNE ロード時間やフレームレートといったパフォーマンスの改善。ビルドでも変化が体感できる可能性がある。
UTILITY 汎用的に使われるであろうコンポーネントや、ロジック・ユーティリティクラスの新規作成・機能追加/変更が主目的のもの。実装が複数PRに渡る場合は全部これにする。
BUGFIX バグの修正。

アセットのPR

プレフィックス前半 使い所
ASSET: アセット(バイナリ + meta)のみの変更のPR。スクリプトやシーン等は一切弄っていないもの。

プレフィックス後半 使いどころ
NEW 新規アセットの追加。組み込みはされていないため、ビルドには直ちに影響しない。
CHANGE 仕様変更や表現の改良のために、新規アセット追加および既存アセットの上書きや削除をしたもの。組み込み済みのアセットについては、ビルドにも影響する。
CLEAN 古い、もう使われていないはずのアセットの削除や、ファイル・フォルダの整理をしただけのもの。

その他のPR

プレフィックス 使いどころ
META コミット忘れとかで発生してしまったmetaファイルをコミットするだけのもの。
OTHER .mdやビルドシステム用のコードなど、Unityプロジェクト自体には関係ないPR。
DO_NOT_MERGE テスト用または作業途中のため、マージしてはいけないPR。実機確認用のビルドを作りたい場合や、実装方針のレビュー依頼を投げる時に使う。

PRを並べるツールを作った

PRプレフィックスのルールは整備できたので、次にPRを分類して並べてくれる簡単なツール『PR並べるマン』を作りました。
https://github.com/komiya-t/PrNaraberuMan

どうせならC#で書いたほうがみんな読みやすいだろうということで、.NET Coreoctkit.netを使いました。dotnet runを使うとNode.jsみたいな感覚で取り扱えて便利ですね。READMEにはMacでの使い方しか書いてませんがきっとWindowsでも同じように動く、そんな気がします。

このツールをプロジェクトのリポジトリの隅にコミットして、エンジニアなら誰でも(.NET Coreを入れれば)すぐに使える状態にしています。Basic認証だったり列挙子名が日本語だったりと大分適当ですが、動いてるからいいんです!

本当はUnityエディタ上でoctokit.netを動かせたら便利だったのですが、残念ながら少なくとも現時点(Unity2018.2, octokit.net v0.32)では無理っぽいです。頑張ってUnity上で動くものを作る場合は、HttpWebRequestを使ってここらへんのAPIを呼ぶ形になるんでしょうか。もっと楽な方法があったら教えてください。

AFTER:ツールを使ったノートを作り

PR並べるマンを使うと以下のような感じで一覧を吐き出してくれるので、 f:id:moyika:20181130150705j:plain

ここからビルドに影響しないものを省いたり、分かりづらいものを訂正したり補足を入れたりしてあっという間にノートを書き上げることができます。元々は運が悪いと1時間ぐらい(!)掛かっていた作業が10分程度で終わるようになりました。

分かりやすいタイトルのPRが多くなったので、変更内容について質問する時間が少なくなったことも理由として大きいです。

また、エンジニアには生の(弄っていない)PR一覧も共有することで、定期的にリファクタリングや新しいユーティリティ等についてなんとなく把握することができるようになったというメリットもあります。

おわりに

ということで、ちょっとしたルールとツールを整備したことによって開発に伴うつらい雑務をかなり軽減できたという話でした!

でもほんとはもっと頑張ればもっとスマートな方法はあるとおもう(無責任)

明日はtackleさんによる『ハイパーカジュアルゲーム「Hoppy Japan」を1ヶ月で作った話』です。

WebGLコンテンツの開発フローと抑えどころ

こんにちは!WebGLおじさんことふかぽんです。

WebGLの案件に関わらせていただくことが多く、「サマーウォーズTV連動特設サイト」や「シン・アリマ」などの案件でもWebGL周りを担当させていただいています。

www.kayac.com

www.kayac.com

過去のアドベントカレンダーではこんなことを書きました。かれこれ4年連続の出場です。

2015 ... WebGLも怖くない!canvasライブラリを効率良く学ぶオススメの順番

2016 ... 【脱・gulp】npm-scriptsでシンプルなフロントエンド開発環境を作る

2017 ... 【WebGL】シェーダーを使って3D空間でスプライトアニメーションさせる


前置き

WebGLコンテンツの開発をさせていただくことが多かったり、社内でWebGLの勉強会を開いたりもしているのですが、ある日ふと、とある技術やテクニックにフォーカスして話すことは多いが開発のフローについて触れることは少なかったなと思い、自分なりの開発フローと、どこに気をつけているかをまとめたいなと思います。

あくまでも全体像の話ですので、jsやシェーダーなど個々の技術のTIPSだったり、パフォーマンスチューニングに関しては触れないです。

実現したいこと

自分の場合は以下に重点をおいて開発を進めています。

  • フィジビリティ確認は早めに
  • 表現の詰めに時間をかけられるように

全体感はこちらです。

1. WebGLライブラリ選定
2. フィジビリティ確認
  - WebGL Report
  - WebGL Stats
  - モック作成
3. フロントエンド開発環境準備
  - ビルド環境
  - シェーダー
4. 検証環境を用意しておく
  - 外部サービス
  - 検証ページ
5. GUIエディターを作る
6. 負荷監視(モニタリング)環境を用意する
  - FPS
  - (threejs限定)renderer.info
7. 本開発
8. 完成

6番に入るころには、このようなGUIが表示されます。

codepen.io

1. WebGLライブラリ選定

WebGLは正式には「WebGL API」のことですが、素のAPIのままだと記述量が膨大になりどうしてもスピード感が出にくいのでライブラリを使うことがほとんどです。

3DコンテンツならThree.js、2DならPIXI.jsを使っています。ドキュメントが詳細にまとまっている点が嬉しいため、長く使っています。

読み込みには、特に制限がなければCDNを使うことが多いです。CDNであればscriptで読み込むだけなのでお手軽さがありつつ、CDNのキャッシュに期待しつつ、という意味で採用しています。

npmモジュールをインポートして適宜importする形をとることもあります。プロジェクトの要件に合わせるのが一番ですので、適宜使い分けていきましょう。

2. フィジビリティ確認

WebGL開発でよく頭を悩ませるのは、挙動の差異がブラウザの種類だけでなくグラフィックドライバーなど端末のハードウェアにも依存してくる点です。

案件ごとで対応する端末の範囲や仕様は全く異なるので、前の案件で問題なかった実装が違う案件でそのまま適用できるとは限りません。 なので、「その仕様は実現可能かどうか」「こういう表現をやってみたいけど導入できるか」を各端末でチェックしておきます。

たいていの場合、この3つを使って確認していきます

2-1. WebGL Report

自分の端末のWebGLの対応状況を表示してくれるサイトです。対応すべき端末でこのページを開いて確認していくことで、使うことのできる機能・できない機能を確認します。

f:id:takumifukasawa:20181130144529p:plain

2-2. WebGL Stats

WebGLのパラメーターやエクステンションが、世の中の端末でどれぐらいまで対応されているかを教えてくれるサイトです。WebGLのエクステンションによっては対応範囲が狭いものもあるので、全体感を知るときに便利です。

f:id:takumifukasawa:20181130144357p:plain

2-3. モック作成

あくまでもフィジビリティ確認が主な目的のモックなので、本開発では使わない前提で作り、対応端末でチェックしていきます。

以前、スマホ限定コンテンツの開発で、10個のループ動画を同時に再生する必要があり、実現するためにスプライトアニメーションを実装することにしたのですが、メモリ的に解像度感の耐えうるテクスチャサイズでその数のスプライトシートを読み込んで表示ができるかがネックだったので、様々なサイズのテクスチャを用意し、読みこむテクスチャの数と大きさをブラウザ上で自由に変更できるようにモックを作り、落とし所を決めました。

本開発においては、他の実装との兼ね合いで予定よりも負荷がかかる場合がほとんどですが、最初に開発方針の目処を立てておけば修正の範囲は少なく済みます

3. フロントエンド開発環境準備

3-1. ビルド環境

最近は流行りに乗ってWebpackをベースにしています。特に制限がなければ、好きなものを使う方針でよいかと思います。

ひと昔前であればGulpを使ったり、npm scripts だけで作っていたりしました。

3-2. シェーダー周り

glslifyを使うことが多いです。glslは使いまわすコードが多いので、よく使うような処理を数多く引っ張ってこれる点でglslifyは便利です。

ちなみによくつかうglslifyのモジュールはこちらです。glsl-noiseは、simplex-noiseなど様々なnoiseを提供してくれています。glsl-blendは、スクリーン、乗算、オーバーレイなど、フォトショのレイヤースタイル的な感覚でブレンド処理をかけることができます。

一方、自分でシェーダーをバンドルするような仕組みを書くこともあります。jsで動的にシェーダーを生成する必要があったためです。

4. 検証環境を用意しておく

WebGLで開発を進めていると、バグを含めた意図しない挙動に出会った時にどこに問題があるかがわかりづらくなることが多いです。jsの実装を間違えていたのか、端末固有のものなのか、数学的に計算を間違えていたのか・・・。 特にシェーダーで、コンパイルエラーが出てないのに意図しない表示になると何がなんだかさっぱりになります。

そこで問題を切り分けるために、開発環境から実装場所を切り離して該当部分だけ検証できるような環境を用意しておきます。

無理に開発環境下ですべてを行わず、機能ごとに切り出していく という点がポイントです。

4-1. 外部サービス

Codepenやjsdo.itはブラウザ上のエディターでjsなどを実行できるのでとても便利です。 検証に関わらず、シェーダーのモックなんかを開発したりもします。

CodePen - Front End Developer Playground & Code Editor in the Browser

jsdo.it - Share JavaScript, HTML5 and CSS

4-2. 検証ページ

案件のアセットを外部サービスにアップロードしてはいけないですが、3Dモデルなどそのアセットじゃないと確認できないものもあります。 そういう時は、開発環境下に検証用のページを作って確認します。

5. GUIエディターを作る

例えばちょっとした数値変更をしたい時に、プログラム上で変更してブラウザで実行して、それを繰り返して・・・は非常に時間がかかります。

そこで、ブラウザ上で挙動を調整できるようなGUIツールを用意しておきます。よく使うのは dat.gui です。数値や色の調整はもちろん関数の呼び出しもできて便利です。threejsやpixijsのexampleでも頻繁に見かけます。

ちょっとした数値変更で思いもよらない動きも出てきたりするので、新たな発見があったりもして楽しいです。

dat.GUI

f:id:takumifukasawa:20181130145812g:plain

また、Three.jsであればOrbitControlsを使ってグリグリ視点を変えられるようにしています。

https://threejs.org/docs/#examples/controls/OrbitControls

6. 負荷監視(モニタリング)環境を用意する

開発を進めていると、気がついたら動作が重くなっていることが起こったりします。いざチューニングしよう!と思ってあれこれ試してみても上手くいかないことはざらです。

パフォーマンスチューニングの際は、何が原因なのかを特定してから進めていく必要があります。そこで、FPSやメモリ周りを画面上に表示しておくことで、パフォーマンスチューニングの元となる指標を可視化するようにしておきます。

原因を特定するフローや問題自体の特定については、こちらの本の第二章「GPU最適化入門」がわかりやすかったので、参考にさせていただいています。

Computer Graphics Gems JP 2015 - コンピュータグラフィックス技術の最前線 -

Computer Graphics Gems JP 2015 - コンピュータグラフィックス技術の最前線 -

  • 作者: 山本醍田,鈴木健太郎,小口貴弘,?吉雄介,白鳥貴亮,向井智彦,五十嵐悠紀,岡部誠,森本有紀,上瀧剛,坂東洋介,加藤諒
  • 出版社/メーカー: ボーンデジタル
  • 発売日: 2015/09/12
  • メディア: 大型本
  • この商品を含むブログ (1件) を見る

6-1. FPS

おそらく、FPSはもっともお手軽にパフォーマンスを確認できる指標だと思います。

自分はよくStats.jsを使っています。CDNもありますし、ちなみに製作者はThree.jsと同じでmrdoobさんです。

const stats = new Stats();
document.body.appendChild(stats);
const tick = () => {
  stats.begin();
  .. 色々な処理
  stats.end();
  requestAnimationFrame(tick);
}
requestAnimationFrame(tick);

f:id:takumifukasawa:20181130151025p:plain

6-2. (threejs限定)renderer.info

threejsであればWebGLRenderer.infoからドローコールやポリゴン数などの情報にアクセスできるようになっています。ドローコールやポリゴン数は特に気にしています。

# 詳しくは https://threejs.org/docs/#api/en/renderers/WebGLRenderer を参照

- memory
  - geometries
  - textures
- render
  - calls
  - triangles
  - points
  - lines
- programs

例えばドローコールであればこのようにアクセスすることができます。

const renderer = new THREE.WebGLRenderer(オプション);
const logElem = document.querySelector(セレクタ);

logElem.textContent = `drawCalls: ${renderer.info.render.calls}`; // ドローコール表示
... その他ログ表示

f:id:takumifukasawa:20181130173412p:plain

7. 本開発

f:id:takumifukasawa:20181130173710p:plain

用意ができたら開発をガシガシ進めていきます。ここまできたら、マークアップや検証、パフォーマンスチューニングが入り交ざりながら開発していきます。適宜npmモジュールが追加されるなど開発環境も変化していきます。

パフォーマンスチューニングは様々なアプローチがあります。繰り返しになってしまいますが、まずは問題を特定できるようにしておくことが肝心です。5番で紹介したような本を参考にしていただければなと思います。

7. 完成

あっという間に完成!

まとめ

ポイントは大きく二つです。

  • ブラウザ上でログを確認できるようにした
  • ブラウザ上で調整できるようにした

本開発にたどり着くまでが長く、開発環境の準備に時間をかけていました。UnityやUnrealEngineなどのゲームエンジンはすでにそれが用意されているので大変便利です。

たしかに、Web開発において、開発者ツールなどを除きそういったGUIのエディターは基本的に存在しませんが、あった方が間違いなく開発を進める手立てになると思います。

最近は WebGLStudio のようなエディター付きのライブラリも出てきていますし、PlayCanvasを使ったコンテンツを見かけることも以前より多くなってきている気がします。また、UnityやUnrealEngineのゲームエンジンのWebGL書き出しも進化してきているので、これからWebGLの開発フローは大きく変わっていくんじゃないかという気がしています。

最後に

ここまで読んでいただいてありがとうございました。

カヤックではWebGLコンテンツをガシガシ開発したいそこのあなたを募集しています。