Quantcast
Channel: Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)
Viewing all 223 articles
Browse latest View live

CTOとエンジニアリングマネージャーでDelegation Boardを作ってみた

$
0
0

こんにちは、ゆのん(id:yunon_phys)です。先日、第二回エンジニアリングマネージャー勉強会にて、タイトルの内容についてLTをしてきました。結構多くの方に興味を持っていただいた内容で、折角なので文章にしてみました。

f:id:yunon_phys:20170223094732j:plain

Management 3.0

Management 3.0によると、内発的モチベーション(同僚による感謝や、自分の能力がしっかり活かせている感)こそが生産性を上げるものだと主張しています。逆に、外発的モチベーションでは生産性が落ちると言われていて、いわゆる、ボーナスや評価などはマイナスにはたらくと言われています。

アカツキでは、誕生日メッセージやサンクスカード、1on1における対話、朝のGood&Newなど、既に内発的モチベーションを高める施策を実施していますが、もっと幸せに働ける職場に出来ないか、というのを常にメンバー自らが探し求めています。そういうわけで、Management 3.0をアカツキ内で学習するというのはそこまでハードルが高いものではありませんでした。

Delegation Board

Management 3.0の実践的なストーリーが書かれているManaging for Happinessを、メンバーの有志で輪読会しようとなりました。この本の三章では、今回の話のメインのDelegation Boardについて書かれています。従来のマネージメント手法では、マネージャーとメンバーの間柄が、指示する側・される側 or 全て移譲する側・移譲される側、と二値しかありませんでした。Management 3.0ではこの指示と移譲の間にさらに5段階設け、以下のように1合計7段階の移譲レベルがあるとしています。

  1. 指示する :管理者として意思決定を行う。
  2. 売り込む :意思決定についての人々を納得させる
  3. 相談する :決定する前に、チームからの意見を得る
  4. 同意する :チームと一緒に決定を下す
  5. アドバイスする :チームによる意思決定に影響を及ぼす
  6. 問い合わせる :チームの決定後のフィードバックを求める
  7. 移譲する :特に影響を及ぼさずチームに任せる

組織としては、時間をかけて出来る限り7に近づくことを目標にします。(いきなり時間をかけると、組織が大混乱に陥る可能性があるので注意)

Delegation Boardをつくるときは、権限移譲したいテーマに対して、Delegation Pokerと呼ばれる7種類のカードをプランニングポーカーのように使います。ポイントは、「せーのっ」で出し合ったカードが異なった時に、認識のすり合わせのためにそれをしっかり議論することです。

CTOとDelegation Boardを作ってみた

Managing for HappinessでDelegation Boardの章を読んだ後、CTOが「よし、これをゆのんとやろう」と言ってきました。というのも、CTOと私の間でどちらが何をやるかを丁度決めていっているところだったのですが、全てCTOから私に権限を移譲して良いのか、もう少し段階があるのではないか、とお互いもやもやと考えていたからでした。もちろん、快諾して、早速やってみました。

f:id:yunon_phys:20170223092438p:plain

上の図が、二人で実施したDelegation Boardです。計18項目に対して、大凡1時間半ぐらいかかりました。

いくつかピックアップしますと、例えばレベル7では、エンジニアミーティング(隔週で開催されるエンジニアのエンジニアによるエンジニアのためのミーティング)や、四半期ごとのエンジニア振り返りのファシリテートといった、ライトなものがあげられました。

f:id:yunon_phys:20170223092703p:plain

一方、エンジニア評価や採用といった、意思決定の難易度が高いものはコミュニケーションをしっかり取って決めていった方が現状は良さそうです。

f:id:yunon_phys:20170223093007p:plain

Delegation Boardを作った感想

Delegation Boardを実際に作ってみると、いろいろな感想が飛び出しました。

認識がずれる!

これまで結構色々なことを二人で意思決定してきたし、大きく意見が対立することも無かったのですが、実際にDelegation Pokerをやってみると、なんとも多くのずれがありました。権限をここまで移譲出来るとうれしいな、というCTOの想いと、ここはCTOが決めようよ、まだ一人で決めるのは不安だよ、という自分の想いの差が現れた結果でしょう。

まだまだCTO依存だなあ

大凡1年半ぐらいかけて、ちょっとずつCTOのやってきた役割をはがしてきたつもりでしたが、レベル3~5に固まっている現状を見ると、まだまだCTO依存だなあと思いました。CTOがもっと技術的な領域に注力すべきフェーズなので、組織マネージメント系はもっと分散させたいところ。

未来にはどうなりたいかを議論しても良いかも

Delegation Boardそのものは現状の認識に使われるものですが、未来にはここはこうなっていたいよねーを議論する材料に使っても良いかと思います。例えば、新卒採用プロセスをまだ相談して決めるレベル(レベル4)だけれど、半年後には最後にどうするかだけ教えてもらえればいいレベル(レベル6)になっていたいね、とか。

多対多に使えるかも

今回は1対1で、普通は1対多で使うものですが、多対多に使えるかもと思っています。例えば、広報部とエンジニアチームの関係。どのカンファレンスのスポンサーになるかを決めるのに、エンジニアチームが全部決めるのか、広報部に一声かけるのか、相談しながら決めるのか、明確にするのに使っても良いかもしれません。(本来の目的とはやや異なりますが)

さいごに

今回作ったDelegation Boardを、せっかくなのでやりっぱなしにするのではなく、定期的にアップデートしていきたいと思います。もっと権限移譲が進み、わくわくしながら強い組織を作っていけるといいですね!


React Conf 2017 現地レポート (1日目)

$
0
0

ライブエクスペリエンス事業部 エンジニアの高松(@shimpeiws)です。 2017/3/13 ~ 14の期間で開催中のReact Conf 2017に参加するためにサンノゼに来ています。

React Conf 2017

つい数時間前に終わったばかりの1日目のレポートを現地からお送りします!

会場の様子

サンノゼ空港近くのSanta Clara Marriottというホテルでの開催です。
インテル博物館がほど近くにあり、IT系企業が多くある地域のようです。

f:id:shimpeiws:20170314072356j:plain

f:id:shimpeiws:20170314072257j:plain

f:id:shimpeiws:20170314072402j:plain

1日目の感想

実際に運用してえられた知見に基づいた実践的な内容が多い一日でした。

全体を通してパフォーマンスの話題が多かったことが印象に残りました。

React Nativeもあり、アニメーションや高度なインタラクションの実現がReactに求められていることが背景にありそうです。

Sebastian Markbageさんのキーノートが特に象徴的でしたが、 SPAの構築でもinitial viewを意識したchunk化やキャッシュの利用などといった、 きめ細やかな設計・実装をすることによってUXのレベルを上げようとする流れを感じました。
実装は、大変になりますね…

個人的には“Next.js: Universal React Made Easy and Simple"の発表が興味深かったです。

Next.jsは"SSRできる環境を簡単に用意できるもの"程度の理解でしたが、 prefetchやオフラインcacheの機構などもあるようで、
これからのWebの要素がちりばめた非常に挑戦的なライブラリだと感じました。


ここからは各セッションの概要とメモです。

セッションは全てストリーミングされ、録画もされているそうなので、録画が後日公開されると思います。
気になるセッションがあれば、後日録画でチェックしてください!!!

Keynote (Tom Occhino, Jing Chen, Sebastian Markbage)

概要

  • FacebookのReactに関わる3人のスピーカーからのキーノート

Tom Occhino

  • 3度目のReact Conf
  • ReactやReact Native、それを支えるコミュニティも非常に大きくなってきた
  • これからもReactを進化させ、革新させていく

Jing Chen

  • Facebookでは多くのアプリでReact Nativeを使っている
  • Facebook Ads ManagerなどでReact Nativeを使ってきたが、Facebook本体のアプリでも部分的にReact Nativeに移行している
  • React Nativeは最初はWeb Viewのリプレイス、次に更新頻度が多いView、View全体へと適用してきた
  • Cross Platform、 Cross Appでも使えると思っている
  • React Nativeを使って、フィードバックしてほしい。コミュニティを育てていきたい

Sebastian Markbage

  • “React Performance End-to-End”というタイトル
  • Reactでの実装は実際に描画されるまでのステップが多く、ボトルネックを生みやすい (Network -> Parse -> Compile -> Heap Init -> Render)
  • それぞれのステップで最適化させていこう
    • Network
      • Initial Viewに欲しいものだけ取得する、 Lazy Loading
      • キャッシュの活用(Service Workerの活用も含む)
      • P2Pの利用
      • Shared Distribution(Shared Versioning, CDN)
    • Parse -> Compile
      • Cache Artifacts(Butecode/Codegen Cache, AOT Compilation)
    • Heap Init
      • Compile(Constant Folding, Heap Snapshoting)
    • Render
  • NetworkはIO、それ以降はCPUボトルネックになる。断片化(Chunk)を軸に最適化していくことができる
    • Networkは時間がかかるので初期に必要な分の取得が完了したら、Prase以降の段階にかかる。
    • ユーザの行動をブロッキングするタイミングが減るので、UXの向上が見込める
    • レンダリングも断片化できる
    • Gestures / Animation -> Tap / Click -> Network / Timer ->ユーザに見えていない部分の更新、の順に早いレスポンスが求められる

A Cartoon Intro to Fiber (Lin Clark)

概要

  • Code CartoonsのLin Clarkさんの発表
  • Reactのアルゴリズムの再実装であるFiberの仕組みをイラストで説明する内容
  • わかりやすい、はずだが、自分のFiberや既存のReactのアルゴリズムの知識がたりないため、あまり理解できず…

メモ

  • 二段階のPhaseがある
    • Phase1 (render / reconciliation)、中断可能
    • Phase2 (commit)、中断不可能
  • priorityがあり、各priority毎にRenderが繰り返される

Next.js: Universal React Made Easy and Simple (Guillermo Rauch)

概要

メモ

  • シンプルかつ、パワフルで動的なリアルタイムアプリケーションを作りたい
    • Universalなプログラミングモデル(React)と言語(JS)を使って実現したい
    • Next.jsのサンプルとしてHacker Newsを真似たHacker Nextを作った
    • zeit.coは1年間 Next.jsで運用されている
  • Next.jsの原理やパターン、将来的な方向性を示す
    • 自動的にCode Splittingする
      • minimalな"設定より規約"の精神で設計されている
        • ./pages配下に各エンドポイント毎のリソースを置く
        • トップレベコンポーネントは独自に定義された “getInitialProps” というライフサイクルメソッドでデータを取得する
      • Code splittingはSPA症候群(トップページでJSの全てのモジュールを読み込むこと)を解決する

React + ES.next = ♥ (Ben Ilegbodu)

概要

  • ES2015やES.nextのフィーチャーを有効活用し、Reactのコードをもっと上手く書こうというTips集的な内容
  • ES5に慣れた人には良い資料になりそう
  • 発表の冒頭で全員立ち上がってスクワットタイムがあったり、GIFアニメーションを多用したスライドがオーディエンスをつかんでいた

メモ

Desctucturing(分割代入)

  • let {comments} = this.stateみたいに書ける
  • 名前付き引数に使える
function MyComponent({children, style}) {
  return (
      <div style={style}>{children}</div>
    )
}

Spread Operator

ArrayやObjectを...fooで展開できる

let {comments} = this.state
let newComment = {...comment, id: 123}
let newComments = [...comments, newCOmments]

applyがいらなくなる

Math.max(...arrayOfValues) // ES2015
Math.max.apply(null, [1,2,3]) //ES5

objectに関して、_.assignもいらなくなる

Arrow Functions

.bind(this)が省ける

Promises

Fetch APIとPromiseのコード例 メソッドチェーンしやすくて良い

Async Functions

async/awaitキーワード

MobX vs Redux: Comparing the Opposing Paradigms (Preethi Kasireddy)

概要

  • MobxとReduxを比較しながら、それぞれの使い所を解説する内容
  • Mobxに関してかなり弱気な雰囲気だった

メモ

  • ReduxもMobxもstate managementのライブラリ
    • ReduxはFluxアーキテクチャの実装、storeはピュアなJS Objectで、Reduerで分割する
    • MobxはStoreがRxで、Viewの該当要素をobserveしている
  • 学習コストの低さ、凝縮性(ドメインクラスが作れるから)はMobxの方が優れている
  • スケーラビリティと保守性の良さ、テスタビリティなどはReduxの方が優れている
  • シンプルなもの、スモールチームでの開発、プロトタイプにはMobxがオススメ
  • 複雑なものにはReduxが良い

Type Systems Will Make You a Better JavaScript Developer (Jared Forsyth)

概要

  • Khan Academyのエンジニアによる、“Flowはいいぞ"という話
  • ReactのProptypesをランタイムの型定義として捉えているのが新しい視点で新鮮だった

メモ

  • JSでデバッグしていて、何でエラーになってるのかわからない時や、逆に何で動いているのかが分からないときがままある
  • もっと型エラーが出て欲しい
  • ツールとしては以下のような分類だが、Static type checkingがオススメ
    • linters
    • チェックツールを作る
    • 実行時の型チェック(ReactのProptypesもこれに含む)
    • Static type checking (Flow)
  • 特にstateに型を書くと不正な状態を防げるので、stateは型を先に書くのがオススメ

React Native in the “Brown Field” (Leland Richardson)

概要

  • Airbnbでは2015年からReact Nativeを試して、2016年からProductionでも利用を開始した
  • Airbnbで開発し、OSS化したnative-navigationを使ったコード例を示しながら、クロスプラットフォームのアプリケーションの実装例を解説していた
  • タイトルのBrown FieldはGreen Fieldの対義として使っているようで、既存のネイティブアプリケーションとReact Nativeを同居させるイメージだと思われる

メモ

  • 2015年の発表後、すぐにReact Nativeを個人的に使い始めた
  • 2016年にはAirbnbとしてもReact Natibeに取り組み始めて、Productionにもリリースした
  • アプリ内ではSwift / Javaのネイティブアプリケーション用のコードと共存しているが、まだJSの割合は少ない
  • ナビゲーションバーやタブ、トランジションなどはプラットフォーム固有の部分が多く共通化するのが難しい
    • 既存のライブラリもたくさんあるが、自社で独自に開発してOSS化した

Moving Beyond Animations to User Interactions at 60 FPS in React Native (Tal Kol)

概要

  • React Nativeはラスト1マイルをこえられるのか?が大きなテーマだ
  • React Nativeにとってのラスト1マイル = 60FPSを常に出せるなめらかなアニメーションの実現で、ネイティブらしいmimic realityを演出するのに必須な要素である
  • react-native-interactableにサンプルがある

メモ

  • React Nativeはラスト1マイルをこえられるのか?
    • 手軽に素早く作れるのは分かるが、ネイティブを本当に置き換えられるのか?
    • そのためには以下2点が必須
      • 60FPSでぬるぬる動くアニメーション
      • mimic realityを与える、ダイナミックなインタラクション
        • inboxの行スライドや、Tinderライクなswipeなどを例にだしていた
    • これらをJSでつくれるのか?
      • 実際的には多少のNativeのスキルセットも必要になる
  • Declarative API(宣言的なAPI)がラスト1マイルを渡りきる鍵になる
    • ユーザインタラクションにとっての宣言的なAPIとはどのようなものか?
    • horizontal / verticalなどの例を示しながら、宣言的なAPIについて解説
    • native driverを書けば初期化の時に宣言的にすれば、ユーザインタラクションでいちいちブリッジしてやりとりする必用がなくなりパフォーマンスが出る
  • Enrich API
    • 豊かな動きを演出する重力や磁石などの効果のAPI設計について解説

ライブエクスペリエンス事業部では一緒にReactで開発してくれる仲間を募集しています!!!

React Conf 2017 現地レポート (2日目)

$
0
0

ライブエクスペリエンス事業部 エンジニアの高松(@shimpeiws)です。

React Conf 2017 現地レポート (1日目)に引き続き、React Conf 2017 2日目の様子をサンノゼの会場から直接お届けします!!!

1日目のセッションの録画がYouTubeにアップされていました!

1日分が1本の動画(8時間25分!)なので見るのに気合がいりますが、 昨日のレポートやスケジュールを見ながら、気になるセッションをぜひチェックしてみてください!

http://conf.reactjs.org/schedule

食事

朝食 + 昼食 + コーヒー・軽食完備です。

ホスピタリティが高い!!!

f:id:shimpeiws:20170315121856j:plain

f:id:shimpeiws:20170315121925j:plain

f:id:shimpeiws:20170315121915j:plain

2日目の感想

ReactVRのセッションから始まったこともあり、1日目と比較すると、よりこれから先の技術にフォーカスされていた印象がありました。

Graph QLでのリアルタイムAPIの構築や、React Storybookによるドキュメンテーションなど、解決しようとしている問題の方向性は違いますが、Reactを使ったプロダクトやチーム開発を一歩先に進めようとする動きだと感じます。

2日間を通して、Reactの開発の中心から、コミュニティの様子・周辺ビジネスまでを肌で感じられた事が、現地にきた一番の収穫でした。


ここからは各セッションの概要とメモです。

Goodbye Flatland! An introduction to ReactVR and what it means for web developers (Michaela Lehr)

概要

  • VRのコンセプトや仕組み
  • ReactVRの概要とコード例
  • UXデザイナーの観点からVRの可能性やその時に考慮すべき事柄について述べられていた
    • “VRはとても魅力的だけど、十分にユーザをケアしてあげなければならない"という観点が終始一貫していた

メモ

  • VRはテクノロジーとの関わり方を変えます
    • Stereoscopic Imagesと、ユーザの回転や移動のセンサリングを合わせることにより、VRは実現される
  • モバイル端末では枠があるが、VRではコンテンツの中にユーザがいる感じ
    • Goodbye, UX metaphor
      • 例えば画像ギャラリーを作るとしても、UX的な抽象は不要で、実際的なギャラリーをVR空間の中に作ることができる
  • ReactVRの概要
    • 光源やUI(ボタンなど)がReactのコンポーネントとして提供されている
    • Flex Boxのレイアウトが使える (flexDirection: 'row'のように)
    • Animated APIがあり、アニメーションがある
  • VRにおけるUXデザイン
    • ユーザの恐怖心をあおってはいけない
    • 正しいスケールを使うこと
    • フレームレートは高く保つこと
    • 固定的をなフォーカス位置を設けること
    • リアル指向よりも抽象的なデザインが良い

Realtime React Apps with GraphQL (Robert Zhu)

概要

メモ

  • 例えばFacebook Messangerやマップなど、変更があった場合にはただちに画面を更新したい
  • リアルタイムなAPIにはPullとPushがある
    • Pull ->ポーリング
    • Push -> Live Query
  • 例えばメールアプリで未読のメッセージをカウントしたい時
    • ポーリング
      • 無駄な通信が多くなってイマイチ
      • 単純でstatelessでプロトタイプやフォールバック用には有用
    • statefullにしてpushすれば最適化できる
      • 重要なメールを受け取った時だけ、メッセージ数をカウントなども可能
  • リアルタイムAPIの設計
    • API Contract
      • なぜpushされたのか、クライアントがセマンティクスを知っていないといけない
    • Subscription Payloads
      • 何をAPIにのせるべきか?
  • GraphQL
    • GraphQLは"Wish Driven Design"
    • クライアントからはレスポンスのキーだけをリクエストする、というのがGraphQLのクエリのイメージ
      • GraphQLが値をセットして返してくれる
  • Demo
    • GraphQLのSubscriptionを使って実装した、メールボックスアプリのデモ
    • コードのイメージとしては以下のような感じだった
const listen = () => {
  const sub = new Subscription();
  sub.subscribe(myCallBack);
}

const myCallBack = (Payloads) => {
  console.info('Callback', Payloads);
}

Jest Snapshots and Beyond (Neehar Venugopal)

概要

  • Dockerのフロントエンドエンジニア
  • JestでSnapshotsを使ってテストをしよう

メモ

  • テストの手法を考えるのが好き
    • 少ない労力でもっとたくさんテストしたいと思っている
    • 2016年からJestを使っている、シンプルで良い
  • Jestで足し算関数のテストを書いてみる
    • watchモードがある
  • Emoji Cinema(inputの入力文字がDBにヒットすると、Emojiの一覧を返すアプリケーション)をどうやってテストする?
    • console.logでemojiを出力してテストコードにコピペするとテストは通るけど…
      • 手動のプロセスが多い
      • 変化に柔軟ではない
      • メンテナンスが辛い
    • そこでSnapshot Testing
      • 足し算関数の例ならば、テストが以下のように書き換わる
        • Before: expect(sum(1,2)).toEq(3)
        • After: expect(sum(1,2)).toMatchSnapShot()
      • ある時点の実行結果をsnapshot(ファイルとして出力される)しておいて、それと同じ結果を得られているかを見る
      • 以下のメリットがある
        • 自動化されたプロセス
        • 変化に強い
        • メンテナンスしやすい
      • Serializeすることもできる
        • expectの形そのままではなく、一定のSerializeのルールに従って変形しておく
      • Componentのテスト
        • react-test-rendererでrenderする
          • expect(component).toMatchSnapshot()
        • Enzyme使えないの? ヒントはSerializers
          • enzyme-to-json/serializer
  • Jestはテストプラットフォーム
  • webpackのconfigをsnapshotでテストする構想がある?

A Beginner’s Guide to Code Splitting Your React App (Neehar Venugopal)

概要

  • モバイルファーストの時代にはパフォーマンスのためにCode Splitting必用
  • 様々なレイヤー、様々なツールでCode Splittingのアプローチをしていく
  • webpack、React Router、 Dynamic Importなどのツール・技術や、コンポーネントの実装方法など、豊富なアプローチで実践的な手段を提供してくれたが、情報量が多すぎて一度聞いただけでは理解できなかった

メモ

  • なぜCode Splittingするか?
    • システムが巨大になって、Javascriptが大きくなりがち
      • 今はモバイルファーストの時代で特に気をつけるべき
  • Long Term Caching
    • app.jsとvendor.jsで分ける
      • ファイル名のハッシュ
      • max-age: inifinity
  • Reactでどう扱うか?
    • LazyLoadコンポーネントを実装する
      • 実装方法としては…
        • Higher Order Component(+ Generator)
        • storeでキャッシュを解決する
        • staticでキャッシュを解決する
        • パラレルにchildrenをlazy loadする?
    • どのレイヤーでコードsplitする?
      • route level splitting
        • 出力されるコードの重複に気をつけよう
      • Component level splitting
    • Responsive Componentsを作る場合は、以下に気をつける
      • モバイルファーストなデザインであること
      • モバイルファーストのCSSであること
      • モバイルファーストのJSであること
      • PCとSPでのテンプレートの切り分けは3つの方法が考えられる
  • API通信するコンポーネントを作ったら、必ずlazy loadにすべき、というのが持論

Web-Like Development and Release Agility for React Native (Parashuram N)

概要

  • マイクロソフトのエンジニア
  • Mobile CenterCode Pushの製品を利用して、WebアプリケーションのようにReact NativeのアプリケーションをCI、デリバリーする
  • 途中でわざとアプリケーションをクラッシュさせたり、デモが上手くて製品の魅力が理解しやすかった

メモ

  • React Nativeは JavaScriptのコードをJavaScipt Coreが解釈し、NativeUIを動かし、イベントを受け取る
  • React Nativeのアプリケーションを配布するにはBuild -> Test -> Sign -> Distributeのプロセスを踏む必用がある
    • Mobile Centerはこれらを統合して提供して提供するクラウド環境
      • ビルド
        • プラットフォームを選択肢、言語やフレームワークを選択する(Androidの例だったので、Java/React Native/Xamarin)
        • 新しいアプリケーションの作成も簡単
      • テスト
        • クラウド上でターゲットデバイスを選択して実行できる
        • Native UIからのイベントをPlugin Registryで受け取って、Event Emitterでクラウド上の各種ターゲットデバイスにブロードキャストしている
        • テストをrecordして実行できる、seleniumのように
      • クラッシュレポーティングもある
      • デバッグはnode.js(node-chakracore)で、VS Codeならばデバッガも利用可能
    • Code Push (Mobile Centerにインテグレートされる予定)
      • 端末への更新の仕組み
      • 今後ABテストもここでできるようになる
    • VS Code for React Native
      • TSサポート
      • ReactNative用の各種エクステンション
      • Deployをエディタから可能、デバッガ利用可能
      • タイムトラベルDebuggingもできる

React-Storybook: Design, Develop, Document and Debug your React UI components (Marie-Laure Thuret)

概要

  • React Storybookによるlive documentationの作り方
  • 開発フローの全ての段階をStorybookは有効に機能する

メモ

  • UIコンポーネントはstateによりかかりがちなもの、どうやったらドキュメンテーションできるのか?
  • React Storybookの概要
    • コードの編集が即座にStorybookに適用される
    • onClick={action('onClick')} Storybook側のロガーに出力も出来る
    • currentPage={number('currentPage', 1)}のように書くとStorybook側のKNOBの項目にinputが追加される
    • Descriptionを書くこともできる
  • API First
  • 壊れないドキュメントを作るには?
  • 保守性はどうなの?
    • デバッグと拡張
      • 新しいフィーチャーを書く時にエンドポイントを足していく
      • デバッグしやすい小さな環境
      • 実際のコンポーネントの振る舞いそのままなので、Storybookの段階でバグを発見できることもある
  • 開発フローの全ての段階をStorybookでカバーすることができる
  • Add-OnのためのAPIもある

Extensible React (Cameron Westland)

概要

  • Autodeskのエンジニア
  • Reactを使った拡張可能な(Extensible)アーキテクチャを作りたい
    • ネストしたコンポーネントで、下から上の階層にイベントを伝搬していく仕組みが拡張性を低くしていると考えた
    • react-slot-fillを開発してこの問題を解決しようとしている

メモ

  • Autodeskのエンジニア、AutoCADなどの製品がある
    • UIが非常に複雑
    • 似たようなコンポーネントだがバリエーションの違うものがたくさんある
  • Goal of Extensibility
    • プロダクトを改善できる開発者の数を増やす
  • Slot & Fillを作った話
    • ReactはRootからコンポーネントを階層的にネストさせていく
    • ユーザインタラクションがあったらイベントを上に伝搬させていく、辛いし、拡張しづらくなる
      • 共通の祖先をもっていることが根本の原因
    • Slot & Fillという概念を追加した
      • Slot.Item = <Fill />みたいに書ける
        • Usageにサンプルあり
      • これによって、Rootからネストする構造を薄く保ち、slotの中に差異を閉じ込めることができる

Taming the Meta-Language (Cheng Lou)

概要

  • Facebookのエンジニア、Reasonの開発チーム
  • ReasonのReactバインドの発表(reasonml/reason-react)
  • (かなり控えめに言って)JSの生産性や文法に問題意識をもっていて、Meta-Languageで解決しようという意識を強く感じた

メモ

  • Reasonを開発している
    • Friendly Syntax & Toolchain Powered by OCaml
    • ElmとF#、Clojureから影響を受けている
    • messenger.com の60%はReasonで書かれている
  • ReasonのReactバインドのreason-reactを開発した
    • JavaScriptでの記述との差異をコード例を示しながら解説
      • propTypes -> types
      • JSX -> function
      • classes -> modules
      • cloneElement -> currying
      • setState -> option state
<MyBanner
  name="hello"
  count=5>
  ...
</MyBanner>
MyBanner.createElement
  name::'hello'
  count::5
  children::[...] ()
/* か、ここに同じJSXを書く */
  • コードを書く以外にもmeetupやチュートリアルの整備など、やることがたくさんあった

パネル・QA

  • Reactの開発者2人(片方はSebastian)、React Nativeの開発者、React Nativeの発表をしていたLeland(Airbnb)、Fiberの発表をしていたLin(mozila)の5人でのパネルディスカッション
    • あらかじめ会場から集めておいた質問にパネラーが答える形式
    • スライドなし口頭のセッションだったので、聞き取れない部分が多く、質問のサマリだけです、すみません!
  • Airbnb製のnative-navigationはreact-navigationとどう違うの?
  • Fiberの今後
  • React Nativeの今後
  • Reactコンポーネントは全部Pure Componentで書くべきなの?
  • CSS in JSの今後

ライブエクスペリエンス事業部では一緒にReactで開発してくれる仲間を募集しています!!!

Unity で Android 向けにビルドが出来ない

$
0
0

Unity Client Engineer の高木(id:Guji)です。

心機一転、4 月から Unity を使い始めた方も多いかと思います。 私も Unity の新卒研修を担当しており、新卒社員に Unity を教えています。

そんな中、私は正常に Android向けにビルド出来たのですが、 新しく Unity をインストールした新卒達は何故かビルドが失敗してしまう事件が起こりました。

MacOS上の Unity 5.6.0f3 で実際出ているエラーは以下の通りです。

f:id:Guji:20170426141125p:plain

Error building Player: CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details. 
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java -Xmx2048M -Dcom.android.sdkmanager.toolsdir="/Users/ユーザ名/Library/Android/sdk/tools" -Dfile.encoding=UTF8 -jar "/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/sdktools.jar" -
stderr[
Error:Invalid command android
]
stdout[
]
exit code: 64

原因は AndroidSDK Tools

原因を調べてみると、最新の Android Studioに付属している SDK Tools が悪さをしているようです。 最新の SDK Tools バージョンは 26.0.1 です。なので、少し古い SDK Tools と入れ替えてみることにしました。

f:id:Guji:20170426142732p:plain

※3 月はアップデートが激しい・・・

直近の過去のバージョンがダウンロード出来ない

注意事項として、公式サイトの日本語版と英語版でアップロードされているバージョンが異なっているようです。

日本語版 f:id:Guji:20170426150624p:plain

英語版 f:id:Guji:20170426150849p:plain

英語版のほうを見てみると、URL に謎の数値が付与されており、25.3.0 / 26.0.0 は URL から類推することは難しそうです。 なので、一先ず 25.2.5 を利用することにしました。

25.1.0 から 25.2.5 までは以下の URL でダウンロード出来ます。

https://dl.google.com/android/repository/tools_rX.X.X-macosx.zip

25.0.0 以前の SDK Tools は以下の URL の X.X.X の部分を変更するとダウンロード出来ます。

http://dl-ssl.google.com/android/repository/tools_rX.X.X-macosx.zip

AndroidSDK Tools を入れ替える

Android Studioと共に SDKをインストールした場合、~/Library/Android/sdk/ に tools があるはずです(Macの場合)。 これを 25.2.5 と入れ替えます。

f:id:Guji:20170426152038p:plain

これで無事、全員 Android向けに Build が出来るようになりました!

新卒エンジニアが国際学会に行ってきたレポート

$
0
0

17新卒エンジニアの森下です。

先日、人工知能系の国際学会に参加してきたので、そのレポートを書きます。

今回参加したのは次の学会です。

14th International Conference on Distributed Computing and Artificial Intelligence (DCAI'17)

投稿したのは自分の大学院の修論の内容なのですが、上司に聞いてみたところ快諾をいただき、参加することとなりました。

学会の様子

今回の学会はポルトガルポルトにあるPolytechnic Institute of Portoという学校で開催されました。

さらに、4学会が同じ会場で開催されており、多くの方が参加していました。

f:id:GuiltyMorishita:20170628224418j:plain

f:id:GuiltyMorishita:20170628225140j:plain

f:id:GuiltyMorishita:20170628224459j:plain

ちなみに、ポルト魔女の宅急便のモデルとなった街らしく、雰囲気がとても良い街でした。

f:id:GuiltyMorishita:20170628225636j:plain

f:id:GuiltyMorishita:20170628225907j:plain

セッションメモ

ここからはセッションについてのメモです。 中でも業務に活かせそうだと思ったものを共有します。

全てのセッションの論文は次の出版社から公開されているため、手法や結果などあまり細かく書けないのが残念です。

www.springer.com

*全文を読むには購入が必要です。

Semantic Profiling and Destination Recommendation based on Crowd-sourced Tourist Reviews - Fátima Leal, Horacio González-Vélez, Benedita Malheiro and Juan Carlos Burguillo

概要

  • 最近、旅行者や観光客は観光関連のレビューにインスピレーションを受け、旅行の予定を立てることが多い
  • このようなレビューは膨大な量のソースがあり、これを利用する旅行者の体験を更に豊かにするために新たなアプローチが必要である
  • この研究では、レビューをセマンティックコンテンツベースのフィルタによって、旅行者の目的地を自動的にリコメンドする手法について提案する

手法

  • 個々のユーザーが選んだレビューに含まれる単語とホテルのデータに含まれる単語の類似度をLDAによって計算する
  • 類似度を元にランク付けし、レコメンドリストとして出力する
  • データはExpediaのレビューを使用

結論

  • レビューの単語の類似度に基づいたレコメンドによって、目的地をユーザーに提案できた(F-measure 78%)

Quality Assessment of Implementation of Strategy Design Pattern - Rafał Wojszczyk

概要

  • ソフトウェア・エンジニアリングにおいて、デザインパターンを使用することはソフトウェアの品質を保証する目的で優れている
  • この研究の目的は、デザインパターンを用いて実装した場合の利点についての例を示すことである

手法

結論

  • ソフトウェア開発のコスト削減をサポートするソリューションを提案した
  • デザインパターンを導入したことによる利点を提示した
  • デザインパターンの実装に関する品質評価モデルについて議論した

The effectiveness of data mining techniques in the detection of DDoS attacks - Daniel Czyczyn-Egird and Rafał Wojszczyk

概要

  • オンラインでの攻撃は正すのが難しく、非常に費用のかかる問題である
  • こういった攻撃を早期に検出するために、ネットワークのデータを分析する様々な手法が存在する
  • この研究では、DDoS攻撃の検出におけるデータマイニング技術の有効性に関する調査結果を示す

手法

  • DDoS攻撃のためのシミュレーションシステム用意し、信頼されたクライアントとそうでないクライアントをシミュレートした。
  • それらのデータをナイーブベイズとk近傍法を使って分類した

結論

  • データマイニング手法を用いた分析では、k近傍法が一番有効性がある結果となった
  • 25%〜36.3%の確率で分類でき、満足のいく結果であった
  • 信頼されたクライアントの7%は間違って分類されていた

Information manipulation and web credibility - Te-Cheng Lu

概要

  • 嘘の情報、ニュース、レビューはこのビッグデータ時代に大きな負担となっている
  • 読み手が嘘を嘘であると見抜けられれば、嘘を書こうとする人も減る可能性がある
  • 嘘の情報拡散を防止するために、情報が真であるとする基準を向上させ、読み手に社会的責任があることを認識させる

手法

  • 書き手は正直者と嘘つきの2種類に分けられる
  • 情報は真実、嘘のような真実、真実のような嘘、嘘に分けられる
  • この4つに有効度をつける
  • 読み手に4つの中から一つを選択させ、その結果により書き手と読み手のスコアがつく
  • スコアが高くなるような戦略をとらせる

結論

  • 読み手が嘘の情報を受け入れないという社会的責任を負わせることで、嘘を書こうとする人に真実の情報を書かかせる戦略を見出した
  • このアプローチはビッグデータ時代におけるウェブの信頼性を向上させる

FOREX trading strategy optimization - Svitlana Galeshchuk

概要

手法

  • 移動平均の勾配の符号をモニタリングする
    • 正から負に変化した時に売りシグナルを出す
    • 負から正に変化した時に買いシグナルを出す
  • 移動平均は低次のものを使用し、取引頻度の最小期間を指定する関数を定義することによりモデル化する
    • 高次の移動平均を利用する場合、取引コストは低くなるが、短期的な収益性の高い取引を逃してしまう

結論

  • 金融市場における取引の意思決定のためのシグナルを遺伝的アルゴリズムにより生成し、検証した
  • 本研究のアプローチは力まかせ探索よりも効率的な高い回収率が示された

感想

国際学会としては今回で3回目の参加となり、緊張もあまりしなくなって非常に楽しめました。 また、初のEUでの学会だったので、いままで参加してきたアジアとはひと味違った雰囲気も良かったです。 大学院を卒業して3ヶ月ほどアカデミックな世界と離れていましたが、改めて面白い世界だと感じました。 将来的に業務と絡めながら論文を出せたらいいですね。 研究室の先生に誘われたときには、すでに入社していたので無理だと諦めていましたが、 新卒が国際学会へ行かせてもらえるアカツキに感謝です。 これからもカンファレンスや学会にガンガン参加していきたいですね!

エンジニア組織マネージメント7つの習慣

$
0
0

この記事はAkatsuki Advent Calendar 2017の4日目の記事です。

こんにちは、ゆのん(id:yunon_phys)です。この記事では、アカツキのVP of Engineering(以下、VP)として、どういったことに日々気をつけてエンジニア組織のマネージメントを行っているのかを述べます。

1. 組織をフラットに保つ

アカツキでは、1人1人の自主性を重んじていて、個人の行動を妨げるようなことを可能な限り排除します。この1つのhowが、組織をフラットに保つということです。階層構造の組織では、上司が部下に指示を出す/部下が上司に許可を求める、という行動を取るようになります。しかし、これは上司が常に正しい意思決定をすることが前提です。実際には現場にいるメンバーの方が正しい意思決定が出来るケースの方が多く、メンバーが自分の判断で行動するほうが合理的であると考えます。自分も立場的に上の立場として見られがちなので、良く◯◯していいですか、という質問が来ますが、許可を求めるな、謝罪せよ、の精神でまずやってみよう、と言うようにしています。

2. 全員で組織をつくる

役割としてはVPがエンジニア組織の責務がありますが、組織をつくるのはそこに属する全員です。このため、各々は必ず善い行動をすると信じ、可能な限り情報をオープンにして意思決定の過程が誰でもわかることを大事にしています。また、何かを決めるときも多数決ではなく、熱量のある人の意見を採用することで、それぞれのメンバーの想いを尊重する風土をつくり、全員が組織づくりに貢献出来るようにしています。

3. ワクワクする個人目標を立てる

個人目標を半年に1度設定しますが、半年後や1年後にどういう人になっていたいかを想像し、それを達成するための行動であったり指標を評価者と握ります。やる前から明らかにむちゃな目標は立てないように注意しつつ、一見むちゃではあるものの出来たらしっかりとレベルアップを実感出来るような、ギリギリ到達可能なラインの目標とします。こうすることで、全員が目標を追いたいと思えるようなものになり、組織としてもより強固になります。

4. マネージメントをエンジニアリングの成れの果てにしない

エンジニアが昇格すると必ずマネージャーになる、というのが昔からある日本企業で良くあります。エンジニアがマネージャーになることしかキャリアパスが無いのが大本の問題点なのに、なぜかエンジニアがマネージャーになることはイケてない(成れの果て)、とされる風潮があります。そこで、エンジニアのマネージャーをイケてる役割とするために、まずマネージメントをやりたくない人にマネージャーを任せないようにしています。技術をひたすら尖らせたい人、プロダクトに最適な技術選定が出来る目を養いたい人向けのキャリアパスアカツキでは用意しています。 また、マネージメントもエンジニアリングと同様に、"スキル"である(先天的に備わったものではない)とし、理論を学び、最新のマネージメントを学習し続けることを推奨しています。その下支えとして、認定スクラムマスター/プロダクトオーナーの研修参加支援、Management3.0の勉強会であったり、プロジェクトでやった施策でやって良かったこと、やらない方が良かったことを共有する場を設けるなどしています。

5. カンファレンスに誰でも行けるようにする

最近ではカンファレンスの発表資料や動画が公開されるので、どういった内容が発表されるかを行かなくても知ることは出来ます。しかし、その場の雰囲気だったり、自分たちが遅れている、といった危機感については、行かなければ体感出来ないものです。こうして体感したものは個人の目線を上げることにつながり、長期的には組織を活性化させるものになると考えるため、手を挙げた人であれば誰でも行けるようにしています1。これまでの実績ベースだと、RubyKaigi、React Conf、LinuxCon、Elixir Conf、Unite、CEDECなどがあります。

6. エンジニアが主体となって採用をする

一緒に働く人は自分たちが決める、の原則の基、エンジニアが前にたって採用活動を行うようにしています。具体的には採用イベントで必ずエンジニアが話すようにしていたり、自分たちが一緒に働きたい人とはどういう人であるかをエンジニア同士で議論したり、インターンの内容・設計を自分たちで行ったりしています。自分たちが達成したいことを実現するために、将来の投資としての採用を重視しています。

7. 量のために採用しない

ブルックスの法則にあるように、遅延しているプロジェクトに人が入ると、さらに遅延していきます。また、急な組織拡大はこれまでに挙げた組織文化を壊す要因となりかねないため、慎重に行っていく必要があります。遅延しているプロジェクトがあれば、なぜ遅延しているのかの原因分析を冷静に行い、今いるメンバーで対処出来る方法が無いかを探します。どうしても採用するとしても、今いるメンバーよりも何かしら優れている要素を持っている人の採用を原則とします。

まとめ

エンジニア組織をマネージメントするにあたり、心がけていることを書いていきました。ここで書いたことは、これからも守り続けるものではなく、メンバーの状態や時代の風潮などによって、変化していくものです。実際これを書いていく過程でも、こうした方がもっと良い組織になるのではないか、というアイデアが湧いてきました。1人1人が輝けるよう、最高の組織とは何かをこれからも追求し続けます。


  1. 本音を言うと、まだまだこちらの想定よりも頻度は少ないので、みんながどんどん申請して、予算取りを困らせるぐらいになって欲しいなあ・・・なんて思います。(そうなっても予算取りを戦い続けるつもりですが)

行列ができるRubyコミュニティ Meguro.rb を主催しました!【発表スライドあり】

$
0
0

この記事はAkatsuki Advent Calendar 2017の記事ではありません(!)

 
こんにちは。エンジニアの天野です。
2017/11/30に弊社で開催したMeguro.rbの様子をレポートします。
 
Meguro.rbとは?
Meguro.rbはRuby地域コミュニティで、目黒駅付近の開発者があつまるRubyの地域コミニティです。
 
現在はLT大会を行っていて、Ruby初心者からコミッターまでの幅広い参加者が、実務に役立つネタからRubyの濃ーい話などを発表しています。
また、懇親会前に参加者全員で自己紹介をする時間を設けていて、懇親会で話すのが苦手!という方にも参加しやすいコミニティになっています。
 
運営は、会場を提供する会社がそのまま受け持つことになっており、今回、運営メンバーに声をかけていただき、弊社で開催する運びとなりました!
 

 

f:id:mutachii:20171204195844j:plain

 
アカツキといえばカレー
 
勉強会と言えば、ビールとピザを食べながらというのが一つの定番になっていますよね。ピザは当日に大量注文することが出来るし、計算しやすいので運営的にもすごく楽です。
 
しかし!
今回は、新しい風を吹かすべく、弊社のカレー好きエンジニアが集結して、特製タイカレーを振る舞いました。

 
内心結構ドキドキでしたが、参加者の反応は...
 

 

 
アカツキのカレーへの情熱は以下の記事を御覧ください)

 
LT
 

f:id:mutachii:20171204195608j:plain

 
参加者の皆さんにカレーとドリンクを楽しんでもらいつつ、10分(発表8分・質問2分)のLTです!
 
RedBlocksの紹介
 
RedisのSorted Setの取り扱いを抽象化した、RedBlockというGemの紹介。
キャッシュキーのマネジメントや最適化メソッドも用意されていて便利そうでした。
  
Rubyのデータサイエンス対応の現状確認

Rubyコミッターである mrkn さんの発表
いくつかあるRubyデータサイエンスのプロジェクトの特徴の紹介でした。12/19(火)に 紹介されたプロジェクトの一つである、Red Data Toolsの東京ミートアップが開催されるようです!

Enter the OSS world [RuboCop] I. presage comment
 

 

kosicさんが開発に参加しているOSS Rubocop の開発についての発表
`Style/MixinUsage`を追加したときの、PRがマージされるまでの議論の様子や、その後のユーザーの反応を紹介していました。
 
本当にあったRailsの怖い話
 

ゲーム開発の中で遭遇したパフォーマンス上のボトルネックを「クエリ神隠し」「クエリ金縛り」「クエリ黄泉がえり」と怖い話風に紹介。
 
 

 「Rubyを256倍使うための本 無道編」を教材に、Raccを利用して自作プログラミング言語を作ってみたという発表。紹介していた本は現在絶版になっているらしく、tommyさんはRubyでつくるRubyもおすすめしていました。
 
tsortについて
 

AWSの料金を売上に紐付けて管理するために、トポロジカルソートというアルゴリズムを利用した話でした。
 
懇親会
 
Meguro.rbでは参加者同士の交流をより深めるための「自己紹介タイム」が恒例になっています。今回はアカツキが毎日行っている「Good and New*1」を行いました。
 
f:id:mutachii:20171204195430j:plain
 
心配していたカレーも無事完売し、楽しいイベントにすることが出来ました!
 

f:id:mutachii:20171204195303j:plain

 
次回予告
 
次回は 12/19(火)開催です!クリスマス前スペシャルと称して、Ruby 2.5.0 縛りでLT大会 という特別企画になります!
アカツキでは引き続き、コミュニティ活性化活動を行っていきます!
 

FactoryGirlのログからテストコストを計測してみた

$
0
0

背景

アカツキではサーバーサイドフレームワークとしてRuby on Railsを採用しており、またそのテスト環境としてRspec/FactoryGirlを使用しています。RoR環境下のテスト体制としてはデファクトスタンダードになっているこの組み合わせですが、主にFactoryGirlの採用については 賛否両論だと言われています。採用を見送るネガティブな要員として、きちんとtraitを管理しないと不必要な関連オブジェクトも芋づる式に生成してしまい、テストの実行時間を大幅に増やしてしまうという問題があります(もっとも、これはFactoryの設計、管理を怠った開発者が原因であり、FactoryGirl自体の罪ではないかもしれませんが)。僕も複雑な条件のtraitの組み合わせや、テストの実行時間に日々悩まされています。

調べてみたこと

しかし実行時間に悩まされているとは言っても、どのFactoryがネックになっているか、ということについて実は確信を持っていないことに気づきました。FactoryGirlリポジトリのGETTING_STARTED.mdにあるものをそのままコピペしてきた、重いfactoryを通知してくれるちょっとしたスクリプトは使っていたのですが、どうにも情報源としてはあんまり有用とはいえません。なのでもっと詳しい情報が得られないか、少しFactoryGirlのコードを調べてみました。

コードを読んでみる

FactoryGirlが教えてくれるこのslow factoryの通知はActiveSupport::Notificationsを利用して行われています(こちらのエントリが詳しいです)。つまりActiveSupport::Notifications.subscribe("factory_girl.run_factory")に対応する通知を送っているところ(Notifications.instrument)がどこかにあるはずなのでそれっぽい単語でソースコードを検索すると、

# @lib/factory_girl/factory_runner.rb

instrumentation_payload = { name: @name, strategy: runner_strategy }

ActiveSupport::Notifications.instrument('factory_girl.run_factory', instrumentation_payload) do
  factory.run(runner_strategy, @overrides, &block)
end

というところが見つかります。このinstrumentation_payloadのhashが通知データとして受け取れるので、factory名とstrategy名はここから取得していたのだとわかりますね。とりあえずデフォルトの状態ではこれ以上はなにも情報を渡してくれていないようです。

しかしながらせっかくこのような仕組みを用意してくれてるのだから、勝手にforkして適当なデータを詰めれないものかとみてみると、辺りによさそうなインスタンス変数やらlocal変数がありますね。

factory = factory.with_traits(@traits)
@overrides = traits_and_overrides.extract_options!
@traits    = traits_and_overrides

factoryというデータが一般的な名前なので色々情報持ってそうだな、と期待できますね。適当にinstrunment_payloadに詰めて見てみると、例えば

# factory.definition.callbacks
=>[]

# factory.definition.attributes
=>, :build}]> 

などのデータが取得できました。他にも様々なデータが含まれており、うまく処理すれば実行されたfactoryのほとんどの情報を得られそうです。

(簡単な情報をparseするgemを作りましたので、よろしければご利用ください。しかしこのinspectorをテストするためのFactoryオブジェクトの生成方法がわからずテストが書けてない……どなたか助けていただけると大変嬉しいです)

せっかくなので集計してみる

適当にFactoryLogなるモデルを通知から生成して、factory名+trait名の組み合わせを一意の識別子としてかかった時間を集計してランキング化してみると

moz.png

と、(どのtraitの)どのfactoryが1つあたり平均どのくらい時間を取り、またどのくらいの量がテスト中に実行されているのか、というデータがわかりました。これにより、例えばテスト時間を短縮したいと思った時にどのfactoryから改善していくか(例えば一部をDBに静的に置いておくようにしたり、mock objectを使うようにするなど)みたいな戦略が立てやすくなりました。

(ちなみにこちらもRails engineとして簡単なgemを書きました。といっても簡単なクラスメソッドをちょこっと書いたモデルがあるだけのものですが……こっちもcontributeお待ちしております)

まとめ

「推測するな、計測せよ」「プログラムの処理にかかる時間の80%はコード全体の20%の部分が占める」とは有名な言葉ですが、OSSのライブラリの場合、デフォルトでは提供されていないような情報も、少し手を加えることで取得できたりすることがあるので、気になったりしたら少しコードを読んで調べてみると、より効率的な業務が可能になるかもしれません。今回はFactoryGirlのコードに少しだけ手を加えてテストデータ生成のコストを計測する方法についてご紹介しました。

おまけ

実はRspecのそれぞれのexample(テストケース)についても、このようにメタデータが取得できます。 また、独自にメタデータを定義もできるようです。うまく使えばテストに対してtag付けして一部のテストのみを設定でskipしたり、fail時に詳細情報を出力するようにしたり色々便利になりそうです。

参考: RSpec 3の重要な変更


新規事業開発をHack!LEAN&SPRINT実践録 <#0.はじめに>

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) こと、赤堀です。エンジニアではなくビズの人間です。

 

さて、突然ですが、僕らのチームでは今こんなサービスを作っています。

joymo.herokuapp.com

 

このサービスはまだベータ版の域を出ませんが、アイディアや検証の仕方について次のような反響をいただいています。

 

この反響をみて、僕らのチームの取り組みを共有することが、世の中に役に立つのかもしれないと思い立ち、ブログで公開していくことにしました。

f:id:poric_ries:20180316125433p:plain

今回は#0ということで、本ブログの目的や背景、今後配信予定のコンテンツなどについてお話します。

 

1.目的

①世の中に新たな価値を生み出そうとするチーム/人の生産性を上げることに貢献したい
アカツキの新規事業に興味・関心を持ってくださる方を増やしたい

 

2.背景

「なぜ、ブログを書こうと思ったか?」

僕らのチームの経験をありのまま共有することが、世の中の役に立つと思ったからです。さらに掘り下げると、次のような背景があります。

 

実践に役立つ新規事業開発ノウハウが共有されていない

スタートアップはもちろん、あらゆる企業で新規事業への取り組みが盛んな昨今にも関わらず、私のようなビズ/ディレクターにとって実践に役立つノウハウは世の中にまだわずかしか共有されていません。

エンジニアにとっては当たり前である、リアルタイムかつリアル(ソースコード含む)な「知の共有」という習慣が、(少なくとも日本の)ビズ/ディレクターにはあまり根付いていません。

 

なぜ、新規事業開発ノウハウは共有されにくいのか?

この要因は、誤解を恐れずにいえば、ビズ/ディレクターにとっては、情報の非対称性を生むことこそが競争優位性であり、自らの経験によって得た貴重な情報を共有するという習慣が根付きにくいためです。

たしかに「あるKPIが分かれば、その事業の成否が透けてしまう」ことは起こりえるため、情報開示に敏感になるのは当然ですが、それに引きづられて、事業成否を映すKPIとは本来”切り離せる”はずのノウハウまで共有されにくく、共有されたとしても抽象化され実践には活かしにくい形になってしまっています。

 

ビズ/ディレクター間でも”知の循環”を促したい 

エンジニアのコミュニティに存在する、実践に即した知の循環(恩恵を受けたら還元する)が回っていない。そんな状況を少しでも改善すべく、本ブログは次のようなコンセプトを設定しています。

 

3.コンセプト

リアル”なノウハウを”リアルタイム”に届ける

リアル

抽象化したノウハウは実践には役に立ちません。実践に役立つのは、抽象化したノウハウにもとづくリアルな実践録です。

一方、抽象化したノウハウは、起きた事象を体系立てて整理したり、そこから真因を抽出し打ち手を講じる際に参考にすることで、振り返り(学び)の精度を上げることには大いに役立ちます。

リアルタイム

日々変化の激しい業界であり、できるかぎり即時性を持ってノウハウを届けることに価値があります。

 

4.ターゲット

新規事業の立ち上げに携わる全てのチーム/人

コアターゲットは企業内新規事業担当者(ビズ/ディレクター)=私と同じ立場の方

  

5.今後配信予定のコンテンツ

冒頭で紹介した「JOYMO」にたどり着くまでの2ヶ月に渡るチャレンジと悪戦苦闘の日々を、会社に怒られるラインのギリギリを狙って、できるかぎり透明性を持って情報公開していきます!

配信予定のコンテンツは以下の通りです。

コンテンツ一覧

#1.今回の新規事業開発における前提・制約条件
アカツキ社、ライブエクスペリエンス事業とは
・今回の前提、制約条件
・新規事業開発プロセスの方針

#2.走り出す前の準備
・メンバー
・必読本
・ファシリティ
・テーマ設定 など

#3.とりあえず走ってみる!Running Lean&SPRINTの実践
・やったこと(時系列でなるべく詳細に)
・結果と振り返り

#4.方法論をチューニングしながら走る!

#5.走り慣れてきた!案外すぐにゴールできるんじゃね!とおもったら...

#6.ターゲットを変えて再スタート!

#7.ダーティー&セクシーな検証

#8.to be determined

 

7.[改めての紹介] 2ヶ月間のランでたどり着いた新サービス「JOYMO(ジョイモ)」

今年1月から走り出した新規事業開発の過程で見つけた新サービスの原石です。まだまだ正式ローンチにはほど遠いものの、ありそうでなかった新しい価値を提供しうるサービスです。

joymo.herokuapp.com

  

以上、いかがでしたか?

 本編#1以降を読みたいと思った方は、ぜひB!&シェアをお願いします!「こんな内容も知りたい」などあればコメントをお待ちしています。


「ユーザーが欲しがるものを作れ!」by Paul Graham@Y Combinator

新規事業開発をHack!LEAN&SPRINT実践録 <#00.はじめに>

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) こと、赤堀です。エンジニアではなくビズの人間です。

 

さて、突然ですが、僕らのチームでは今こんなサービスを作っています。

joymo.herokuapp.com

 

このサービスはまだベータ版の域を出ませんが、アイディアや検証の仕方について次のような反響をいただいています。

 

この反響をみて、僕らのチームの取り組みを共有することが、世の中に役に立つのかもしれないと思い立ち、ブログで公開していくことにしました。

f:id:poric_ries:20180316125433p:plain

今回は#0ということで、本ブログの目的や背景、今後配信予定のコンテンツなどについてお話します。

 

1.目的

①世の中に新たな価値を生み出そうとするチーム/人の生産性を上げることに貢献したい
アカツキの新規事業に興味・関心を持ってくださる方を増やしたい

 

2.背景

「なぜ、ブログを書こうと思ったか?」

僕らのチームの経験をありのまま共有することが、世の中の役に立つと思ったからです。さらに掘り下げると、次のような背景があります。

 

実践に役立つ新規事業開発ノウハウが共有されていない

スタートアップはもちろん、あらゆる企業で新規事業への取り組みが盛んな昨今にも関わらず、私のようなビズ/ディレクターにとって実践に役立つノウハウは世の中にまだわずかしか共有されていません。

エンジニアにとっては当たり前である、リアルタイムかつリアル(ソースコード含む)な「知の共有」という習慣が、(少なくとも日本の)ビズ/ディレクターにはあまり根付いていません。

 

なぜ、新規事業開発ノウハウは共有されにくいのか?

この要因は、誤解を恐れずにいえば、ビズ/ディレクターにとっては、情報の非対称性を生むことこそが競争優位性であり、自らの経験によって得た貴重な情報を共有するという習慣が根付きにくいためです。

たしかに「あるKPIが分かれば、その事業の成否が透けてしまう」ことは起こりえるため、情報開示に敏感になるのは当然ですが、それに引きづられて、事業成否を映すKPIとは本来”切り離せる”はずのノウハウまで共有されにくく、共有されたとしても抽象化され実践には活かしにくい形になってしまっています。

 

ビズ/ディレクター間でも”知の循環”を促したい 

エンジニアのコミュニティに存在する、実践に即した知の循環(恩恵を受けたら還元する)が回っていない。そんな状況を少しでも改善すべく、本ブログは次のようなコンセプトを設定しています。

 

3.コンセプト

リアル”なノウハウを”リアルタイム”に届ける

リアル

抽象化したノウハウは実践には役に立ちません。実践に役立つのは、抽象化したノウハウにもとづくリアルな実践録です。

一方、抽象化したノウハウは、起きた事象を体系立てて整理したり、そこから真因を抽出し打ち手を講じる際に参考にすることで、振り返り(学び)の精度を上げることには大いに役立ちます。

リアルタイム

日々変化の激しい業界であり、できるかぎり即時性を持ってノウハウを届けることに価値があります。

 

4.ターゲット

新規事業の立ち上げに携わる全てのチーム/人

コアターゲットは企業内新規事業担当者(ビズ/ディレクター)=私と同じ立場の方

  

5.今後配信予定のコンテンツ

冒頭で紹介した「JOYMO」にたどり着くまでの2ヶ月に渡るチャレンジと悪戦苦闘の日々を、会社に怒られるラインのギリギリを狙って、できるかぎり透明性を持って情報公開していきます!

配信予定のコンテンツは以下の通りです。

コンテンツ一覧

#1.今回の新規事業開発における前提・制約条件
アカツキ社、ライブエクスペリエンス事業とは
・今回の前提、制約条件
・新規事業開発プロセスの方針

#2.走り出す前の準備
・メンバー
・必読本
・ファシリティ
・テーマ設定 など

#3.とりあえず走ってみる!Running Lean&SPRINTの実践
・やったこと(時系列でなるべく詳細に)
・結果と振り返り

#4.方法論をチューニングしながら走る!

#5.走り慣れてきた!案外すぐにゴールできるんじゃね!とおもったら...

#6.ターゲットを変えて再スタート!

#7.ダーティー&セクシーな検証

#8.to be determined

 

7.[改めての紹介] 2ヶ月間のランでたどり着いた新サービス「JOYMO(ジョイモ)」

今年1月から走り出した新規事業開発の過程で見つけた新サービスの原石です。まだまだ正式ローンチにはほど遠いものの、ありそうでなかった新しい価値を提供しうるサービスです。

joymo.herokuapp.com

  

以上、いかがでしたか?

 本編#1以降を読みたいと思った方は、ぜひB!&シェアをお願いします!「こんな内容も知りたい」などあればコメントをお待ちしています。


「ユーザーが欲しがるものを作れ!」by Paul Graham@Y Combinator

新規事業開発をHack!LEAN&SPRINT実践録 <#01.走り出す前の準備>

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) こと、赤堀です。ひとり一人の人生の思い出を増やすために、おすすめのお出かけを提案するサービス「JOYMO(ジョイモ)」を作っています。

joymo.herokuapp.com

 

 僕らのチームでは、Running LeanやSPRINTなどのメソッドを実際に導入し、僕らなりにカスタマイズしながら、新サービスを立ち上げています。

 

前回#0で宣言した通り、”実践録”を順次配信していきます。 

hackerslab.aktsk.jp

 

f:id:poric_ries:20180322231449p:plain

第1回のテーマは <走り出す前の準備> です。

 

 

0.アカツキ、ライブエクスペリエンス事業とは

JOYMOは、アカツキのライブエクスペリエンス事業内の取り組みなので、前段として簡単に会社と事業の紹介をします。

 

アカツキとは

「感情を報酬に発展する社会」の実現を目指し、主力であるモバイルゲーム事業に加え、リアルな体験を届けるライブエクスペリエンス事業をはじめとして、世界にワクワクとつながりをもたらす様々な事業を展開しています。

f:id:poric_ries:20180322213022p:plainf:id:poric_ries:20180322213202p:plain

●ライブエクスペリエンス事業とは

ライブ(生の、リアルな、ワクワクする)・エクスペリエンス(体験)の意味で、 厳選したアウトドアレジャー専門予約サイト「そとあそび」や遊び・体験予約サイト「Wowful(ワオフル)」の運営をはじめ、子会社「アカツキライブエンターテイメント」を通じてサバイバルゲーム事業やイベント事業等を展開しています。

 

 

1.新規事業の制約条件を整理する

企業内で新規事業を立ち上げる場合、組織なので当然ながら制約条件があります。

 

まず、新規事業の目的やゴール(期待値)、守るべきことを制約条件として整理します。これを予め経営とすり合わせておかないと、あとで大変です。実際僕らもここで一度躓きました。

 

本ブログでは、制約条件の中身というよりも整理の仕方の参考例として、僕らのチームのやり方を共有します。

 

僕らのチームでは、「ビジョナリー・カンパニー2」の”針鼠の概念と三つの円”に基づいて条件を設定しました。

 

f:id:poric_ries:20180322222151p:plain

 

具体的には、次のように条件を言語化しています。 

 

[情熱を持って取り組めるものであること]

①次のミッションを実現できること
すべての人々に「やりたい!行きたい!」との幸せな出会いを提供し、人生の思い出を増やしていく。いつでもどこでも、それがすぐに叶う未来をつくる。
補足)ライブエクスペリエンス事業が掲げるミッションのひとつです。

②リーダー(私自身)が情熱を注げること

 

[自社が世界一になれるものであること]

③事業ドメイン
衣食住ではなく余暇(エンターテイメント)を主目的とした領域であること

 

[経済的原動力になるものであること]

④売上規模
数十億円〜百億円/年を目指せること
補足)ゲーム事業と両輪をなすための目線感です。

⑤ビジネスモデル
CtoCモデルを採用すること

 

 

2.メンバーを集める

「スタートアップとは、とてつもなく不確実な状態で新しい製品やサービスを作り出さなければならない人的組織である 」(by Eric Ries)

 

アイディアよりプロダクトより何よりまずチームが最も重要だと信じています。今回のチーム編成では、次に2つを判断軸にアカツキ社内でリクルーティングし、メンバーを集めました。

 

①プロダクトを作る最小単位のチームであること
ディレクター、デザイナー、フロントエンドエンジニア、サーバーサイドエンジニアを入れた5名チームを編成


②100%コトに向き合えるチームであること
必要以上に人に対して気を遣わず、率直な物言いができる(その前提となる信頼関係を築けている)メンバーでチームを編成

 

 

●ここだけは譲らない

今回のチーム編成は私が全てを決めることができました。企業内新規事業では非常に珍しいことだと思いますが、それでも敢えて言えば、他のどんな裁量を譲ったとしてもここだけは死守すべきだと感じています。

 

 

 

3.新規事業開発プロセスの方針を決める

●規律あるチャレンジ

アカツキでは、新規のゲームやサービス開発の失敗からの学びとして、”規律あるチャレンジ”を重視しています。規律(制約)があるからこそ創意工夫を繰り返し、その結果としてイノベーションが生まれると信じています。

 

僕らのチームでは、これを実践に落とすために、次に2つのメソッドを採用しています。

 

メソッド1.LEANに進める

LEANな進め方、つまり、

ビジネスプランの重要な部分から、
順番に仮説検証し、
その学びを生かして柔軟にプランを変えながら、
成功に近づいていくプロセス

を採用して進めています。

 

前提知識として「アントレプレナーの教科書」「リーン・スタートアップ」を 共通言語にした上で(ここは4.で後述します)、実践面では「Running Lean」をメインの教科書としています。

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)

 

具体的には、リーンキャンバスを用いてプランの要素を言語化したり、その優先順位にしたがって仮説検証したり、ユーザーインタビューの質問項目に本の内容を取り入れるといった形で最大限活用しています。

 

 

メソッド2.SPRINTで回す

「Running Lean」は、体系的なプロセスをわかりやすく整理しているものの、実際の現場の回し方はイメージしにくいものです。そこで、日々の進め方のメソッドとして採用したのが「SPRINT」です。 

 

SPRINTは、Google Venturesが推奨する

アイディア創出からその検証までを高速で行ない、短時間でアウトプットを出す

フレームワークです。

SPRINT 最速仕事術――あらゆる仕事がうまくいく最も合理的な方法

SPRINT 最速仕事術――あらゆる仕事がうまくいく最も合理的な方法

 

f:id:poric_ries:20180323104310p:plain

 

この2つのメソッドの根幹にある思想は次の3つです。

  • 最も重要なことに集中する
  • 問いを立てて、検証して、答えを出す(学ぶ)
  • 最小最速で取り組む

ここが共通しているからこそ、異なるメソッドながら組み合わせて活用することができます。

 

 

4.脳内一致の土壌を作る

僕らのチームは5名ながら、職種はもちろんキャリアも全く異なるため、使う言葉やその定義、価値観が違います。

チームで相乗効果を発揮するためには、全員の脳内を常に一致させ、各々の自由なアイディアや意見をぶつけ合って高め合うことが何より重要です。 

 

●必読書

この土壌を作るために、次の5冊を必読書に定め、チーム全員で同じインプットをしました。 

 

ステップ1.前提知識を叩き込み、共通の価値観で、同じ言葉を使う。

アントレプレナーの教科書[新装版]

アントレプレナーの教科書[新装版]

 

 

リーン・スタートアップ

リーン・スタートアップ

 

 

ステップ2.新規事業開発プロセスを理解する。 

 
ステップ3.企画初期に重要なユーザーインタビュー方法を学ぶ。
リーン顧客開発 ―「売れないリスク」を極小化する技術 (THE LEAN SERIES)

リーン顧客開発 ―「売れないリスク」を極小化する技術 (THE LEAN SERIES)

 

 

 

なによりもまず読むべきは「アントレプレナーの教科書」冒頭60ページ!

顧客がいるかどうかの確認もせず、莫大な資金と貴重な時間を費やして大失敗するプロジェクトの物語を反面教師とし、LEANの思想をベースにムダのないプロセスを第一とする価値観を全員ですり合わせました。

 

 

5.環境(というか座席)を作る

アカツキは、目黒の新築ビルに入居しています。
カラフルでオシャレな内装で、植物もあり、すごく開放的な空間で働いています。

https://aktsk.jp/images/recruit/album/images_02.jpg

 

一方、僕らのチームは、通称精神と時の部屋と名付けた、狭く閉鎖的な部屋に”あえて”席を設けました。

f:id:poric_ries:20180323113729j:plain

 

●「精神と時の部屋」の狙い

  1. 距離が近く、密なコミュニケーションがとれる
  2. 他のチームから切り離され、自由にアイディアや意見を出せる
  3. なんだかベンチャー感がある 

実際やってみて一番重要だと感じたのは”2”です。
傍から聞くと馬鹿げた発言も、実はブレイクスルーのきっかけになることはよくあることですが、思いついたことを”率直に発信できる心理状態を保つ”のは結構難しく、意識的/無意識的にチーム外の人を反応を気にしてしまう環境はチームにとってネガティブに働きます。心理的安全な環境を物理的に作り出す工夫が必要です。

 

 

以上、今回は走り出す前の準備として、事業と組織(チーム)両面で事前に整えておくべきことをお話しました。

 

いかがでしたか?

 

次回は「#2.とりあえず走ってみる!Running Lean&SPRINTを実践してみた」です。僕らのチームが最初に取り組んだ”ファミリー層の課題”について、具体的にどんな課題設定をして、どう検証したか、時系列に沿い実際の風景やプロトタイプも見せながら共有します。お楽しみに!


「完璧を目指すよりまず終わらせろ!」by Mark Elliot Zuckerberg@Facebook

リーン・スタートアップはもう古い?企業内新規事業でよみがえるLeanな事業立ち上げ <#00.はじめに>

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) こと、赤堀です。エンジニアではなくビズの人間です。

 

さて、突然ですが、僕らのチームでは今こんなサービスを作っています。

joymo.herokuapp.com

 

このサービスはまだベータ版の域を出ませんが、アイディアや検証の仕方について次のような反響をいただいています。

 

この反響をみて、僕らのチームの取り組みを共有することが、世の中に役に立つのかもしれないと思い立ち、ブログで公開していくことにしました。

f:id:poric_ries:20180316125433p:plain

今回は#0ということで、本ブログの目的や背景、今後配信予定のコンテンツなどについてお話します。

 

1.目的

①世の中に新たな価値を生み出そうとするチーム/人の生産性を上げることに貢献したい
アカツキの新規事業に興味・関心を持ってくださる方を増やしたい

 

2.背景

「なぜ、ブログを書こうと思ったか?」

僕らのチームの経験をありのまま共有することが、世の中の役に立つと思ったからです。さらに掘り下げると、次のような背景があります。

 

実践に役立つ新規事業開発ノウハウが共有されていない

スタートアップはもちろん、あらゆる企業で新規事業への取り組みが盛んな昨今にも関わらず、私のようなビズ/ディレクターにとって実践に役立つノウハウは世の中にまだわずかしか共有されていません。

エンジニアにとっては当たり前である、リアルタイムかつリアル(ソースコード含む)な「知の共有」という習慣が、(少なくとも日本の)ビズ/ディレクターにはあまり根付いていません。

 

なぜ、新規事業開発ノウハウは共有されにくいのか?

この要因は、誤解を恐れずにいえば、ビズ/ディレクターにとっては、情報の非対称性を生むことこそが競争優位性であり、自らの経験によって得た貴重な情報を共有するという習慣が根付きにくいためです。

たしかに「あるKPIが分かれば、その事業の成否が透けてしまう」ことは起こりえるため、情報開示に敏感になるのは当然ですが、それに引きづられて、事業成否を映すKPIとは本来”切り離せる”はずのノウハウまで共有されにくく、共有されたとしても抽象化され実践には活かしにくい形になってしまっています。

 

ビズ/ディレクター間でも”知の循環”を促したい 

エンジニアのコミュニティに存在する、実践に即した知の循環(恩恵を受けたら還元する)が回っていない。そんな状況を少しでも改善すべく、本ブログは次のようなコンセプトを設定しています。

 

3.コンセプト

リアル”なノウハウを”リアルタイム”に届ける

リアル

抽象化したノウハウは実践には役に立ちません。実践に役立つのは、抽象化したノウハウにもとづくリアルな実践録です。

一方、抽象化したノウハウは、起きた事象を体系立てて整理したり、そこから真因を抽出し打ち手を講じる際に参考にすることで、振り返り(学び)の精度を上げることには大いに役立ちます。

リアルタイム

日々変化の激しい業界であり、できるかぎり即時性を持ってノウハウを届けることに価値があります。

 

4.ターゲット

新規事業の立ち上げに携わる全てのチーム/人

コアターゲットは企業内新規事業担当者(ビズ/ディレクター)=私と同じ立場の方

  

5.今後配信予定のコンテンツ

冒頭で紹介した「JOYMO」にたどり着くまでの2ヶ月に渡るチャレンジと悪戦苦闘の日々を、会社に怒られるラインのギリギリを狙って、できるかぎり透明性を持って情報公開していきます!

配信予定のコンテンツは以下の通りです。

コンテンツ一覧

#1.今回の新規事業開発における前提・制約条件
アカツキ社、ライブエクスペリエンス事業とは
・今回の前提、制約条件
・新規事業開発プロセスの方針

#2.走り出す前の準備
・メンバー
・必読本
・ファシリティ
・テーマ設定 など

#3.とりあえず走ってみる!Running Lean&SPRINTの実践
・やったこと(時系列でなるべく詳細に)
・結果と振り返り

#4.方法論をチューニングしながら走る!

#5.走り慣れてきた!案外すぐにゴールできるんじゃね!とおもったら...

#6.ターゲットを変えて再スタート!

#7.ダーティー&セクシーな検証

#8.to be determined

 

7.[改めての紹介] 2ヶ月間のランでたどり着いた新サービス「JOYMO(ジョイモ)」

今年1月から走り出した新規事業開発の過程で見つけた新サービスの原石です。まだまだ正式ローンチにはほど遠いものの、ありそうでなかった新しい価値を提供しうるサービスです。

joymo.herokuapp.com

  

以上、いかがでしたか?

 本編#1以降を読みたいと思った方は、ぜひB!&シェアをお願いします!「こんな内容も知りたい」などあればコメントをお待ちしています。


「ユーザーが欲しがるものを作れ!」by Paul Graham@Y Combinator

リーン・スタートアップはもう古い?企業内新規事業でよみがえるLeanな事業立ち上げ <#01.走り出す前の準備>

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) です。ひとり一人の人生の思い出を増やすために、おすすめのお出かけを提案するサービス「JOYMO(ジョイモ)」を作っています。

joymo.herokuapp.com

 

 僕らのチームでは、Running LeanやSPRINTなどのメソッドを実際に導入し、僕らなりにカスタマイズしながら、新サービスを立ち上げています。

 

前回#0で宣言した通り、”実践録”を順次配信していきます。 

hackerslab.aktsk.jp

 

f:id:poric_ries:20180322231449p:plain

第1回のテーマは <走り出す前の準備> です。

 

 

0.アカツキ、ライブエクスペリエンス事業とは

JOYMOは、アカツキのライブエクスペリエンス事業内の取り組みなので、前段として簡単に会社と事業の紹介をします。

 

アカツキとは

「感情を報酬に発展する社会」の実現を目指し、主力であるモバイルゲーム事業に加え、リアルな体験を届けるライブエクスペリエンス事業をはじめとして、世界にワクワクとつながりをもたらす様々な事業を展開しています。

f:id:poric_ries:20180322213022p:plainf:id:poric_ries:20180322213202p:plain

●ライブエクスペリエンス事業とは

ライブ(生の、リアルな、ワクワクする)・エクスペリエンス(体験)の意味で、 厳選したアウトドアレジャー専門予約サイト「そとあそび」や遊び・体験予約サイト「Wowful(ワオフル)」の運営をはじめ、子会社「アカツキライブエンターテイメント」を通じてサバイバルゲーム事業やイベント事業等を展開しています。

 

 

1.新規事業の制約条件を整理する

企業内で新規事業を立ち上げる場合、組織なので当然ながら制約条件があります。

 

まず、新規事業の目的やゴール(期待値)、守るべきことを制約条件として整理します。これを予め経営とすり合わせておかないと、あとで大変です。実際僕らもここで一度躓きました。

 

本ブログでは、制約条件の中身というよりも整理の仕方の参考例として、僕らのチームのやり方を共有します。

 

僕らのチームでは、「ビジョナリー・カンパニー2」の”針鼠の概念と三つの円”に基づいて条件を設定しました。

 

f:id:poric_ries:20180322222151p:plain

 

具体的には、次のように条件を言語化しています。 

 

[情熱を持って取り組めるものであること]

①次のミッションを実現できること
すべての人々に「やりたい!行きたい!」との幸せな出会いを提供し、人生の思い出を増やしていく。いつでもどこでも、それがすぐに叶う未来をつくる。
補足)ライブエクスペリエンス事業が掲げるミッションのひとつです。

②リーダー(私自身)が情熱を注げること

 

[自社が世界一になれるものであること]

③事業ドメイン
衣食住ではなく余暇(エンターテイメント)を主目的とした領域であること

 

[経済的原動力になるものであること]

④売上規模
数十億円〜百億円/年を目指せること
補足)ゲーム事業と両輪をなすための目線感です。

⑤ビジネスモデル
CtoCモデルを採用すること

 

 

2.メンバーを集める

「スタートアップとは、とてつもなく不確実な状態で新しい製品やサービスを作り出さなければならない人的組織である 」(by Eric Ries)

 

アイディアよりプロダクトより何よりまずチームが最も重要だと信じています。今回のチーム編成では、次に2つを判断軸にアカツキ社内でリクルーティングし、メンバーを集めました。

 

①プロダクトを作る最小単位のチームであること
ディレクター、デザイナー、フロントエンドエンジニア、サーバーサイドエンジニアを入れた5名チームを編成


②100%コトに向き合えるチームであること
必要以上に人に対して気を遣わず、率直な物言いができる(その前提となる信頼関係を築けている)メンバーでチームを編成

 

 

●ここだけは譲らない

今回のチーム編成は私が全てを決めることができました。企業内新規事業では非常に珍しいことだと思いますが、それでも敢えて言えば、他のどんな裁量を譲ったとしてもここだけは死守すべきだと感じています。

 

 

 

3.新規事業開発プロセスの方針を決める

●規律あるチャレンジ

アカツキでは、新規のゲームやサービス開発の失敗からの学びとして、”規律あるチャレンジ”を重視しています。規律(制約)があるからこそ創意工夫を繰り返し、その結果としてイノベーションが生まれると信じています。

 

僕らのチームでは、これを実践に落とすために、次に2つのメソッドを採用しています。

 

メソッド1.LEANに進める

LEANな進め方、つまり、

ビジネスプランの重要な部分から、
順番に仮説検証し、
その学びを生かして柔軟にプランを変えながら、
成功に近づいていくプロセス

を採用して進めています。

 

前提知識として「アントレプレナーの教科書」「リーン・スタートアップ」を 共通言語にした上で(ここは4.で後述します)、実践面では「Running Lean」をメインの教科書としています。

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)

 

具体的には、リーンキャンバスを用いてプランの要素を言語化したり、その優先順位にしたがって仮説検証したり、ユーザーインタビューの質問項目に本の内容を取り入れるといった形で最大限活用しています。

 

 

メソッド2.SPRINTで回す

「Running Lean」は、体系的なプロセスをわかりやすく整理しているものの、実際の現場の回し方はイメージしにくいものです。そこで、日々の進め方のメソッドとして採用したのが「SPRINT」です。 

 

SPRINTは、Google Venturesが推奨する

アイディア創出からその検証までを高速で行ない、短時間でアウトプットを出す

フレームワークです。

SPRINT 最速仕事術――あらゆる仕事がうまくいく最も合理的な方法

SPRINT 最速仕事術――あらゆる仕事がうまくいく最も合理的な方法

 

f:id:poric_ries:20180323104310p:plain

 

この2つのメソッドの根幹にある思想は次の3つです。

  • 最も重要なことに集中する
  • 問いを立てて、検証して、答えを出す(学ぶ)
  • 最小最速で取り組む

ここが共通しているからこそ、異なるメソッドながら組み合わせて活用することができます。

 

 

4.脳内一致の土壌を作る

僕らのチームは5名ながら、職種はもちろんキャリアも全く異なるため、使う言葉やその定義、価値観が違います。

チームで相乗効果を発揮するためには、全員の脳内を常に一致させ、各々の自由なアイディアや意見をぶつけ合って高め合うことが何より重要です。 

 

●必読書

この土壌を作るために、次の5冊を必読書に定め、チーム全員で同じインプットをしました。 

 

ステップ1.前提知識を叩き込み、共通の価値観で、同じ言葉を使う。

アントレプレナーの教科書[新装版]

アントレプレナーの教科書[新装版]

 

 

リーン・スタートアップ

リーン・スタートアップ

 

 

ステップ2.新規事業開発プロセスを理解する。 

 
ステップ3.企画初期に重要なユーザーインタビュー方法を学ぶ。
リーン顧客開発 ―「売れないリスク」を極小化する技術 (THE LEAN SERIES)

リーン顧客開発 ―「売れないリスク」を極小化する技術 (THE LEAN SERIES)

 

 

 

なによりもまず読むべきは「アントレプレナーの教科書」冒頭60ページ!

顧客がいるかどうかの確認もせず、莫大な資金と貴重な時間を費やして大失敗するプロジェクトの物語を反面教師とし、LEANの思想をベースにムダのないプロセスを第一とする価値観を全員ですり合わせました。

 

 

5.環境(というか座席)を作る

アカツキは、目黒の新築ビルに入居しています。
カラフルでオシャレな内装で、植物もあり、すごく開放的な空間で働いています。

https://aktsk.jp/images/recruit/album/images_02.jpg

 

一方、僕らのチームは、通称精神と時の部屋と名付けた、狭く閉鎖的な部屋に”あえて”席を設けました。

f:id:poric_ries:20180323113729j:plain

 

●「精神と時の部屋」の狙い

  1. 距離が近く、密なコミュニケーションがとれる
  2. 他のチームから切り離され、自由にアイディアや意見を出せる
  3. なんだかベンチャー感がある 

実際やってみて一番重要だと感じたのは”2”です。
傍から聞くと馬鹿げた発言も、実はブレイクスルーのきっかけになることはよくあることですが、思いついたことを”率直に発信できる心理状態を保つ”のは結構難しく、意識的/無意識的にチーム外の人を反応を気にしてしまう環境はチームにとってネガティブに働きます。心理的安全な環境を物理的に作り出す工夫が必要です。

 

 

以上、今回は走り出す前の準備として、事業と組織(チーム)両面で事前に整えておくべきことをお話しました。

 

いかがでしたか?

 

次回は「#2.とりあえず走ってみる!Running Lean&SPRINTを実践してみた」です。僕らのチームが最初に取り組んだ”ファミリー層の課題”について、具体的にどんな課題設定をして、どう検証したか、時系列に沿い実際の風景やプロトタイプも見せながら共有します。お楽しみに!


「完璧を目指すよりまず終わらせろ!」by Mark Elliot Zuckerberg@Facebook

やってはいけない!新規事業チームの最悪な1週間の過ごし方

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) です。

 

僕らのチームでは、Running LeanやSPRINTなどのメソッドを実際に導入し、僕らなりにカスタマイズしながら、新サービス「JOYMO(ジョイモ)」を作っています。

joymo.herokuapp.com

 

本ブログは、

「リーン・スタートアップはもう古い?企業内新規事業でよみがえるLeanな事業立ち上げ」

をテーマに、新規事業開発現場の”実践録”をシリーズで配信しています。

 

▼配信済
#0.はじめに 
#1.走り出す前の準備
#2.やってはいけない!新規事業チームの最悪な1週間の過ごし方 ← 今回はここ

▼配信予定
#3.方法論をチューニングしながら走る!
#4.走り慣れてきた!案外すぐにゴールできるんじゃね!と思ったら...
#5.ターゲットを変えて再スタート!
#6.ダーティー&セクシーな検証
#7.to be determined

 

 

今回はいよいよSPRINT開始!1周目の実践録を配信します。

f:id:poric_ries:20180331150258j:plain

 

教科書通りに実践してわかった”本と実際の違い”や”躓きポイント”など、このブログを読んで実際にやってみようと思った方に役立つことを中心に話します。

 

 

[前提] チームのミッションと3ヶ月の過ごし方

1.チームのミッション

  • 3ヶ月間でProblem/Solution Fitを完了すること
  • アウトプットとして「MVP」をローンチすること

これが僕らのチームのミッションでした。このミッションを達成するために、Running LeanとSPRINTを組み合わせて進めることを決めました。(背景は#1を参照)

 

 

2.あらためて「SPRINT」とは

デザイン思考やIDEOのメソッドをベースにGoogle Venturesが開発したプログラムで、開発やローンチなく、アイディアを形にしてユーザーテストして学びを得る(Idea to Lean)、5日間のプログラムです。

f:id:poric_ries:20180403120921p:plainThe sprint gives teams a shortcut to learning without building and launching.

引用元:Google Ventures Web Site

 

新規サービスを立ち上げるにあたり、Running Leanに沿って最小最速で価値検証を進めたいが、ぶっちゃけ現場をどう回したらよいかわからん!と思った矢先に見つけたのがこの「SPRINT」でした。

 

f:id:poric_ries:20180403121859p:plain

参考:「SPRINT」を詳しく知るための書籍&サイト

 

3.三ヶ月の過ごし方

このSPRINTにもとづき、3ヶ月の過ごし方を計画しました。

はじめの2ヶ月でSPRINTを5周回して課題/ソリューションを決め、残りの1ヶ月でMVPと事業計画を作る。正直どうなるかわからないけど、とにかく走り始めました。

f:id:poric_ries:20180331133252p:plain 

 

 

 

[結果] 1周目はあえなく失敗!!!

結論から言うと、1周目のチャレンジはあえなく失敗しましたorz
なお、ここでの”失敗”の定義は「ユーザーに関する学びが得られなかったこと」と定義します。

 

1周目は”とにかく教科書通りに”と決めてタスクは進めていたものの、振り返れば、タスクの目的やそれに適した品質を見極めきれずに進めた部分があり、それが要因となって失敗しました。

 

失敗の原因はここだった!

次の2点です。

  1. ターゲット(誰のどの瞬間に焦点を当てるか)があいまいだったため、適切なフィードバックが得られなかった。
  2. プロトタイプが”リアル”さを欠いていたため、適切なフィードバックを得られなかった。

結果、最大の成果であるはずの「ユーザーに関する学び」を得られませんでした。

 

 

 

 

[経緯] 1周目を時系列で振り返る

何をどのように進めたら失敗したのか?今後チャレンジする方の参考になるように、ポイントは絞りつつ、背景や流れがわかるように時系列で説明します。

 

1.スケジュール

f:id:poric_ries:20180403124715p:plain

 

 

2.SPRINT前にやったこと

2-1.三ヶ月で取り組むテーマを決める

SPRINTに入る以前に、そもそも僕らのチームはまだ何をやるか決めていませんでした。新規事業の制約条件(#1参照) を前提に「何に取り組むべきか?」をまずは決める必要がありました。

 

▼アイディアを持ち寄る

 そこで、Running Leanで採用している「リーンキャンバス」を用い、「顧客セグメント」「課題」「独自の価値提案」をメンバー各々がリストに書いて、それをもとに議論しました。

docs.google.com

※アイディアリストを公開します。チームで相談し、ドキュメントも出来る限りオープンにします。

 

▼テーマを決める

議論を経て、次の順で取り組むことを決めました。

  1. [顧客] 子連れファミリー
    [課題] 子供と一緒に行けるお出かけ先が見つからない 
  2. [顧客] アクティブな独身 / DINKs男女
    [課題] 行きたいところはあるが、一緒に行く人が見つからない
  3. [顧客] 最近残業の減ったビジネスパーソン
    [課題] 平日夜に何をしたらよいかわからない

 

 

2-2.顧客を知る

最初に取り組む「子連れファミリー」を深く知るべく、社内のパパ・ママに”子供とのお出かけ”にまつわる課題をインタビューをしました。

インタビューは、実際にお出かけするまでの流れを書き出し、何に困っているかをヒアリングしたり、例えば実際にスマホで情報を探す姿を観察して、気付きを得る形で進めました。

f:id:poric_ries:20180403172305p:plain ※現場の雰囲気を伝えるために画像掲載しています。画像が荒く内容は読めませんがあしからず。 

 

パパ・ママの悩みの理解が進んだところで、いよいよSPRINTを開始しました! 

 

 

3.SPRINT開始

3-1.月曜日:目標を決める

月曜日はSPRINTの目標を決めます。具体的には次の3つです。

●決めること

  1. 長期目標
  2. SPRINT Question(このSPRINTで答えを出すべき問い、以降SQと表記)
  3. ターゲット(誰の、どの瞬間を対象にするか)

f:id:poric_ries:20180401124516p:plain

 

正直、それぞれをどの粒度で決めて進めば良いのか不確かでした。

SPRINTの教科書に出てくる事例は、既存サービスの抱える具体的な問題を扱うケースが多く、課題や対象者が明確です。僕らのように”新規サービスまるっと”という大きな粒度のものはありません。悩みつつも、月曜日の終わりに決まった内容はこちらです。 

▼決まったこと

  1. 長期目標
    ファミリーに対して「やりたい!行きたい!」との幸せな出会いを提供し、人生の思い出を増やすこと
  2. SQ
    どうすればファミリー(パパ・ママ)は納得の行くお出かけ先が見つけられるか?
  3. ターゲット
    誰:子供を持つパパ・ママ
    瞬間:お出かけ先を探して決めるとき

これを残りの4日間の道標としました。 

 

 

失敗ポイント①:ターゲットがあいまい

1つ目の失敗ポイントは、ここで設定したターゲットがあいまいだったことです。

 

”ファミリー”とひとくちに言っても、両親の職業(共働きか否かなど)や、子供の年齢/性別/趣味嗜好によって休日の過ごし方は大きく異なりますし、課題も異なります。ユーザー理解は進めてはいたものの、肌感がまだ鈍く、具体性に欠ける、不明確なターゲットの設定となっていました。

 

これが原因で、ソリューション検討やテスト対象者選定などの後続タスクが適切に進められず、結果としてユーザーに関する学びを十分に得ることができませんでした。

 

【教訓】最速で検証できる(繰り返せる)からこそ、ぐいっとターゲットを絞り込み、明確に定義したほうが学びの精度は上がる

 

 

3-2.火曜日:目標を決める

SQとターゲットが決まったら、次はソリューションを作ります。

火曜日はアイディアを集めて適した形に改良します。既存のサービスをとにかく使ってみて、役立ちそうな既存ソリューションを集めて共有し、そのインプットをもとに全員が手を動かし、ソリューションを文字通り”手描き”しました。

 

 

3-3.水曜日午前:ベストを決める

水曜日は数あるソリューションの中から、プロトタイプを作ってテストするものを決めます。 

今回の問い(SQ)「どうすればファミリーは納得のいくお出かけ先が見つけられるか?」で焦点を当てたのは「納得のいくお出かけ先を選ぶ基準として最も重要な要素が何か?」という点でした。

 

●2つのプロトタイプ

この点に対してソリューションが2つあり、結局チームを2つに分けました。

  1. 選ぶ基準=人軸
    サービス名「eXer(エクサー)」:自分(パパ・ママ)の属性に近しい人のおすすめするお出かけ先を探せる・選べる
  2. 選ぶ基準=効果・効能軸
    サービス名「JOYMO(ジョイモ)」:何を学べるか(効果・効能)軸でお出かけ先を探せる・選べる

 

 

3-4.水曜日午後:幻想をつくる

アイディアが決まれば、次はプロトタイプ作成です。

 

●プロトタイプ作成

ツールは Keynoteを使いました。広告からWeb/アプリ画面まで全てのクリエイティブをこれで作り、リンク機能を使って画面遷移させました。このツールのメリットは、職種問わず全員が扱える=分業作業に適している点です。

 

実際に2つのプロトタイプ(各10画面程度)を2名ずつ手分けして、半日で作ったものがこちら(eXer / JOYMOはファイル紛失)です。

 

 

3-5.木〜金曜日: テストする

1日前倒しでプロトタイプ作成が終わった僕らは、意気揚々とユーザーテストを開始しました。

 

●ユーザーテストの風景

全員で同じ情報をインプットできるよう、appear.in を使ってユーザーテストの様子をリモートで観察しました。

f:id:poric_ries:20180402110820p:plain

 

結果は・・・プロトタイプに必要なある部分を決定的に欠いたため、ユーザーから適切なフィードバックを得られず、SQに対する答えを得ることはできませんでした。

 

失敗ポイント②:”リアル”さの欠けるプロトタイプ

さて、SPRINTの最大のメリットのひとつが、開発すると数ヶ月掛かるプロダクトを、たったの1日でプロトタイプを作ってユーザーに触ってもらい、学びを得られるという点です。

 

そして、これが成り立つための欠かせないポイントが、

プロトタイプは”リアル”に見えなくてはいけない 

です。

 

教科書に明確に書いてあったにも関わらず、その重要性を十分理解しておらず、僕らの最初のプロトタイプはこの”リアルさ”を著しく欠いていました。

 

リアルさを欠いた部分は次の2点です。

  • コンテンツの数が少なくて、そもそも探せる状態になっていない
  • 動線が1つしかなく、選ぶ行動(複数のコンテンツを見比べる等)ができない

要は、納得のいくお出かけ先を探して選ぶまでのUX(普通の使い方)を実現できないプロトタイプだったため、テストがワークしませんでした。

 

正直「このレベルなら自分たちで気付けよ」とツッコミたいですが、「このくらいでもわかってくれるだろう」というユーザーに対する安易な期待があったのだと思います。

 

【教訓】ターゲットを絞り込んだ上で、検証したいUXを実現しうる必要最小限のプロトタイプを作成すること。

 

 

 

まとめ

この5日間を通して、次のことを学びました。

教訓

  1.  最速で検証できる(繰り返せる)からこそ、ぐいっとターゲットを絞り込み、明確に定義したほうが、学びの精度は上がる。
  2. ターゲットを絞り込んだ上で、検証したいUXを実現しうる必要最小限のプロトタイプを作成すること。
具体的な改善策「ターゲットを明確に定義する」

そもそもここでターゲットを具体化できない場合、顧客の理解が足りない可能性が高いため、SPRINTに入る前に今一度「顧客を知る」ことが必要。

具体的な改善策「プロトタイプの品質を上げる」
  1. コンテンツの質と量を上げる
    ・選べるくらいコンテンツの数を揃える(例:一覧で最低2、3スクロール可)
    ・ユーザー毎にコンテンツを準備する(例:居住地に近いコンテンツを揃える)
  2. 探して選べる動線を作る
    Prottを使い、Keynoteで作った画面を繋ぎ合わせ、画面遷移を作る。メリットは、画面遷移が直感的UIでとにかく簡単に作れること。

 

また、今回SPRINTを導入することで仕事の基本動作/スタンスを改めて学ぶこともできました。

 

基本動作/スタンス

  • 何事にも時間を決めて取り組む
    時間枠(5日間、10〜18時)内で成果を出すと決めたことで、小さなタスクまで時間を決めて取り組むことで、単純なことなのに生産性が劇的に上がった。
  • 脳内一致する
    同じインプットを受けるだけでなく、分からなかったら率直に聞く、思いつきでもいいから意見があれば怖がらず共有するなど、当たり前の徹底でアイディアを高め合えた。
  • ユーザーに使ってもらう
    「人の欲しがるものを作れ」の根本。ユーザーから直にフィードバックをもらう大切さを改めて学んだ。

 

以上、いかがでしたか?

 

とにかく学びは多かったものの、手順や基本動作に関するもの多く、ユーザーに関する学びは2周目以降に期待!ということで、次回は「#3.方法論をチューニングしながら走る!」です。

 

次回もお楽しみに!

新規事業担当者の陥りがちな心理と対策

$
0
0

こんにちは、ライブエクスペリエンス事業部のポリック (id: poric_ries) です。

 
本ブログは、

リーン・スタートアップはもう古い?企業内新規事業でよみがえるLeanな事業立ち上げ

をテーマに、新規事業開発現場の”実践録”をシリーズで配信しています。

 

▼配信済
#0.はじめに 
#1.走り出す前の準備
#2.やってはいけない!新規事業チームの最悪な1週間の過ごし方
#3.新規事業担当者の陥りがちな心理と対策 ← 今回はここ

▼配信予定
#4.新たな企画での再スタート!ダーティー&セクシーな検証
#5.to be determined

 

 

今回は、LEAN&SPRINT実践手法から少し離れ、企業内で新規事業を企画する際に担当者が陥りがちな心理とその対策について書きます。見ようによっては、やや後ろ向きな内容で書くかどうか迷ったのですが、企業内新規事業が盛んな昨今、同じ立場で同じ悩みを抱えている方はいるんじゃないかと思い、思い切って配信することにします。

 

f:id:poric_ries:20180509103953p:plain

 

 

 

 

新規事業担当者が陥りがちな、望ましくない心理とは?

その心理とは「新規サービスを作ること」自体を目的にしてしまうことです。

企画段階に限っていえば「企画を通すこと」を目的化してしまうことです。

 

(ここで記載する内容は”当たり前”の内容ですが、自分が当事者として”わかっちゃいるけど”なかなかに苦しんだことであり、同じ境遇の方に向けて学びと対策を共有します)

 

なぜ、この心理に陥ってしまうのか?

前提として、企業内新規事業は起業とは異なり、会社のリソース(資金、人材等)を投資してもらってはじめて取り組めるものであり、当然ながら企業内ゆえの制約条件があります。

  • 会社のビジョン/ミッションとの整合性
  • 会社の事業ポートフォーリオ
  • 予算、投資回収期間
  • 将来的な事業規模
  • 既存事業との親和性、シナジー
  • 人材育成、ノウハウ蓄積
  • 最終決裁者の思い、好み etc... 

企業内新規事業担当者は、これらの制約条件を前提に、
「自分/チームのやりたいこと、熱意を込められること」と「ユーザーの求めること」の結節点(新規事業の種)を探り、企画を作っていきます。

 

(今書いてみても思うんですが、なかなか難易度が高い)

 

さらに、組織の中で短期的にも成果を出す(少なくとも”やってる感を見せる)必要性に迫られたあげく、

 

f:id:poric_ries:20180513124900p:plain



 

という心理に陥ってしまいます。

 

これに陥ってしまうと・・・

新規サービスを作ること/企画を通すことが目的になると、思考も行動も望ましい状態から離れていきます。

f:id:poric_ries:20180513125858p:plain


こんな状態で企画したサービスは成功しませんよね・・・運良く企画が通ったとしても、ユーザーに向き合わなければユーザーの欲しがるものは作れないですし、なによりも自分もチームも成功に向けて100%で走り続けられないからです。

 

(私の場合)チームの貴重な"2週間”をロス!

前回#2で進めていた企画。検証が進むにつれ、私の心では、なかなか”燃えてこない”ヤキモキを感じると同時に、期限内に企画を通さなければならないという焦りがありました。その焦りが次第に強くなるにつれ、知らず知らずのうちに「本当にこれがやりたいサービスなのか?」という問いに対して、この企画を通すためには”「YES」と答えなければいけない”と自分に言い聞かせようとする心理が働いていました。

 

私の場合、幸運にも望ましくない心理に陥りきらなかったのは、チームメンバーの存在でした。

「やりたいことをやってください!!!」

私の心理を知ってか知らずか(おそらく感じ取っていた)メンバーから率直なフィードバックを受け、

「こんなに恵まれている環境で、やりたいことやらなかったら一生後悔する。」

ということを痛感し、結果的に大きく方向転換し、ターゲットをファミリーから独身へ舵を切りました。

 

この方針転換自体は、LEANでいうピボット(仮説検証で積み上げた学びを踏まえての戦略転換)ではなくリセットでした。LEANやSPRINTの実践手法に関する学びは蓄積したものの、最も優先すべき「ユーザーに関する学び」を次に活かすことができないという失態をおかしました。結果、チームの貴重な約2週間という時間を棒に振ってしまいました。

 

ひとえに私が未熟だったというのはもちろんありますが、企業内新規事業を担当する方が陥る可能性のある心理なので、反面教師として参考になれば幸いです。

 

どうすれば、望ましくない心理に打ち勝つことができるか?

私なりの答えは、唯一、自分とチームに対して誠実でいることです。

 

仮に自分とチームをダマしながら企画を進めたとしても、どこかで必ず躓きます。そのとき「やっぱりやめた」「はじめからやりたくなかった」はありえませんし、百歩譲って自分の信頼がガタ落ちするのはいいとしても、この企画に投資した”自分とチームの時間”はどんなに努力しても取り戻せません。

 

この点を強く意識し、「ダメだ」と思ったら率直にチームに打ち明ける勇気をリーダーは持つべきだと思います。それが自分とチームの貴重な時間を投資することに対しての、最低限の責務だと思います。

 

望まない心理に陥っていないかセルフチェック

具体的には、次のような問いを自分自身に定期的に問うことにしています。

  • 自分とチームの貴重な時間を、この事業/サービスに投資してよいのか?
  • あと1年しか生きられなくても、この事業/サービスをやりたいのか?
  • 自分の身銭を切ってでも、この事業/サービスをやりたいのか? etc...

できれば、自分自身とそしてチームと率直に話し合うことをおすすめします。

 

 

心機一転、再スタート

解決すべき最良の問題は、自分が個人的に抱えている問題である by ポール・グレアム

 

私の場合、自分が熱意を持てるテーマは、自分自身が課題の当事者であること(自分がユーザーであること)が重要だと気付きました。世の中にはもちろん、自分自身はユーザーでないにも関わらず、ユーザーに向き合って、手に取るようにユーザーを理解して、素晴らしいサービスを生み出す人もたくさんいるし、そうなりたいとどこかで思っていました。でも、今の自分では無理でした。 

 

これは”良し悪し”の話ではなく、自分自身がリーダーとして責任と裁量を持って意思決定して進めるためには、この「自分が個人的に抱えている問題」の解決を図るしかないと決めました。この詳細は次回以降にお話します。

 

以上、いかがでしたか?

 

余談:「企業内新規事業は上手くいかない」と言われて久しいですが(私は信じていません)、最近読んだ次の記事も参考になりました。弊社も当てはまる部分/当てはまらない部分がありますが、考えさせられた良記事です。

blog.zerotoone.jp

 

[宣伝] ”デートのマンネリ化”にお困りの方は必見!!!

僕らのチームでは、Running LeanやSPRINTなどのメソッドを実際に導入し、僕らなりにカスタマイズしながら、新サービス「JOYMO(ジョイモ)」を作っています。

joymo.herokuapp.com

彼女や奥さんからの「週末、どうする?」にお困りの方は、ぜひ一度試してみてください。

 

 

 


Server Sonic 2018 開催レポート

$
0
0

こんにちは、エンジニア採用担当の花田です。
この度8月25日(土)〜26日(日)に今年で第2回目の開催となる新卒エンジニア向けインターンシップ「Server Sonic 2018(通称:サバソニ)」を開催いたしました。その様子を紹介させていただきます。

「Server Sonic 2018(通称:サバソニ)」とは・・・

2日間を通して、ゲームサーバーアプリケーションの性能改善方法を学び、Akatsuki x KADOKAWAが贈る青春体験型野球ゲーム「八月のシンデレラナイン」(ハチナイ)の性能改善に2人1組で取り組み、結果を競い合うという内容です。

▼詳細はこちらhttps://aktsk.jp/recruit/new_recruit2020/serversonic2018/

#なぜこのようなインターンシップアカツキが実施するのか
一言で言うと「ワクワクする体験を通して、学びを得てもらいたい!」という気持ちからです。

エンジニア職を目指す学生とお会いする中で、多くの学生から「個人やサークル規模では体験できないインターンシップに参加したい」という声を聞いていました。

そこで、社内のエンジニアチームとどうすれば、「個人やサークル規模では体験できないインターンシップ」を開催できるかを話し合い、実際にリリースされている大規模プロダクトのソースコードに触れることができるインターンシップを企画しました。昨年も同様の思いから、第1回を実施しましたが「難易度が高い」「単なる高速化ではなく、プロダクトとして良質なコードを書きたい」という意見から、1日開催から2日間の開催へと変更し、講義パートの比重を大きく変更しコンテスト自体にゲーム性を加える事で、参加者がワクワクし、のめりこめるような内容を企画いたしました。

数ヶ月に渡る準備期間を経て、 いよいよ開催当日。

▼会場入口

f:id:kenji-hanada:20180829195000p:plain
会場の入口にはハチナイメンバーが勢揃いし、参加者を迎え入れる

まずは、アカツキの文化として根付いている「Good & New」(24時間以内にあった「よかった事」「新しい気づき」の共有)でアイスブレイク。他社のインターンなどで顔を合わせていたり、まさかの同じサークルに所属しているメンバーもいたりと、朝から話が弾み、笑いが生まれる和やかな雰囲気でスタート。

▼Good & New

f:id:kenji-hanada:20180829195005p:plain

その後、アカツキメンバーから性能改善に関する講義を入門編&応用編と二部構成にて実施。特に応用編は難易度の高い内容でしたが、参加者からも質問が飛び、積極的に吸収し、午後の開発に向け知識を蓄えている姿が印象的でした。

▼性能改善に関する講義

f:id:kenji-hanada:20180829195009p:plain

講義を終えたところで、いよいよ開発開始。

各チーム、それぞれの得意領域から役割分担をし、開発を進めます。ゲーム構成のどの部分を改善すると結果が得られそうか、仮説を立てながら取り組んでいました。

▼いよいよ開発開始

f:id:kenji-hanada:20180829195014p:plain

 開発中にはアカツキのメンターが、参加者の質問に答え、開発をサポート。Slack上での質問や、画面を眺めながらの対応と、2日間を通し活発なコミュニケーションを取っていました。

 ▼参加者の質問にはメンターがサポート

f:id:kenji-hanada:20180829195019p:plain
また今回、CI(継続的インテグレーション)を回すことで、改善結果がポイントとして表示される仕組みを構築したため、参加者はテスト実施の度に、ワクワクしたり、時には思う様に結果が得られず落ち込んだりと開発そのものに含まれたゲーム性を楽しんでいました!

 ▼テストを試す度にポイントを表示

f:id:kenji-hanada:20180829195024p:plain

このポイントは、途中経過としてチーム名を伏せて、参加者に公開し、自分たちが今、何番手に位置しているのかということを把握することで、終盤は熱いデッドヒートが繰り広げられました。

あっという間に開発時間が過ぎ、いよいよ結果発表へ!緊張高まる中、順位が発表され、優勝チームは両手を高らかにハイタッチをして喜びを噛み締めていました^^

今回、準優勝チームにはアカツキオリジナルパーカーを、優勝チームにはSwitch、PS4 Pro、Kinesisなどの豪華賞品から希望のものを贈りました。

 ▼優勝・準優勝チーム

f:id:kenji-hanada:20180829195027p:plain

その後、CTOの田中から、順位に限らず参加者からの優れたコミットの発表(優秀コード部門、ネタ部門など)があり、そのコードを書いた参加者が意図を話して、2日間を振り返りました。

▼CTO田中からの優れたコミットを発表

f:id:kenji-hanada:20180829195031p:plain

インターンシップの締めくくりは、懇親会。アカツキの子会社であるアカツキライブエンターテイメントが提供するgoodyというケータリングを囲み、参加者とメンターが和気藹々と交流しました。

▼懇親会の様子

f:id:kenji-hanada:20180829195035p:plain

#最後に、運営側としての感想

至らぬ点もあったかと思いますが「ワクワクする体験を通して、学びを得てもらいたい」という思いは幸運にも参加者のみんなに伝わったと感じています!結果を残せて喜んでいるメンバーや、自分の力不足に悔しさを見せるメンバー、それぞれの表情を見ながら、みなさんの今後の成長と活躍がとても楽しみになりました。参加者のみなさん、今回の振り返りを経て得た学びを、是非次なるステージに繋げていただければと思います^^

▼参加者のみなさん、本当にお疲れ様でした!

f:id:kenji-hanada:20180829195040p:plain

Akatsuki Game JAM 開催レポート

$
0
0

こんにちは、エンジニア採用担当の花田です。

去る9月8日(土)〜9日(日)に2020年新卒エンジニア向けインターンシップ「Akatsuki Game JAM」を開催いたしました。今年で第4回となるその様子を「Server Sonic 2018(通称:サバソニ)」に続き、紹介させていただきます。

「Akatsuki Game JAM」とは・・・

2日間を通して、ゲームアイデアの企画から開発までを行い、その制作物の結果を競い合うという内容です。今回は、アカツキで大切にしている「つながり」「Shine(輝く)」という2つの言葉をテーマにUnityでのチーム開発を行います。参加者は17人、5チームです。

 ▼詳細はこちら

https://aktsk.jp/recruit/new_recruit2020/gamejam2018/

#なぜこのようなインターンシップアカツキが実施するのか

私たちは本気で「ゲーム開発を通して、世の中をワクワクさせるようなプロダクトづくりを体験をしてもらいたい!」という想いを持っているからです。

もちろん、参加者の中にはこれまでにもハッカソン参加の経験や、サークルなどでのチーム開発を経験している参加者も多くいました。一方で、多くの学生とお話をする中で、プロのエンジニアから近い距離でアドバイスをもらいながら、開発を進める経験をしたことがある学生は少なく、その機会を創出したいと思い開催しています。今年で4回目になりますが、毎年パワーアップしております。

#昨年から何を変えたのか

このインターンシップでは、アカツキの組織文化も一緒に体現できるインターンシップにしたいと考えました。そのため、従来の1日開催から2日間に期間を拡大し、更にアカツキのエンジニアが各チームの専任メンターとしてつくことで、より濃密なコミュニケーションが取れる様に変更を加えました。
併せて期間拡大により時間的余裕が生まれたことで、ワクワクするアイデアを生み出すためのアイデアソンの充実化や、オフィス見学、各チームの制作物の試遊会、アカツキの振り返りの文化も体験してもらう事ができました。

#当日の様子

春から多くの学生との面談や面接を実施して、いよいよ開催当日を迎えます。

インターンシップでも恒例となった「Good & New」(24時間以内にあった「よかった事」「新しい気づき」の共有)でアイスブレイクをし、早速開発ゲームのアイデアソンへと移ります。

▼Good & New

f:id:kenji-hanada:20180912163252j:plain▼アイデアソンの説明

f:id:kenji-hanada:20180912163255j:plain今回この段階では、アイデアは全参加者のものという考えのもと、全チームのゲーム企画を共有し、発想を拡げた後に、各チームがブラッシュアップするという方法をとりました。チーム戦ではあるものの、より多くのアイデアに触れることで、企画が磨かれていくのを感じました。

▼アイデアを張り出し、全チームに公開

f:id:kenji-hanada:20180912163259j:plainゲーム企画が決まったところで、いよいよ開発開始です。2日間の開発スケジュールや役割分担を決め、本番が始まるこの瞬間に、会場の雰囲気も一層熱を帯びた様に感じました。今回、各チームを専任メンターが担当し、参加者からの質問対応や、適宜アドバイスと、交流も積極的に。VRゲームを開発するチームに対し、Oculus Goを貸与した為、初めて触るメンバーは環境構築に手こずりながらも、奮闘していました。

▼いよいよ開発開始、メンターからのアドバイス

f:id:kenji-hanada:20180912163302j:plain2日間に拡大したものの、開発時間はあっという間に過ぎ、成果物のプレゼンテーションへ。

各チーム、そのゲームのこだわりポイントや面白み、また当初想定していた機能が時間が足りずに実装に至らなかった悔しさを口にしながらも、全力で取り組んだこの2日間をアピールしました。

▼プレゼンテーションの様子

f:id:kenji-hanada:20180912163312j:plain発表に対しては、アカツキメンバーと参加者から様々な質問が飛びました。質問は「実装にはどんな技術を使用したのか」「盛り込めなかった機能が実装されれば、どのように面白みが拡がるか」「コンセプトが尖っているが、どのような発想から生まれたのか」など、時に会場は笑いにつつまれながら、発表を終えました。
アカツキメンバーからの質問タイム

f:id:kenji-hanada:20180912163316j:plain発表後には、各チームのゲームを体験できる試遊会を実施。自分たちのゲームを他チームに説明、体験する側ものめり込んでプレイする姿が印象的でした。2日間に拡大したことで、参加者が全力を注ぎ込んだプロダクトに触れる時間を設けることができ、お互いの健闘を称える良い時間となりました。

▼試遊会

f:id:kenji-hanada:20180912163306j:plainそして、いよいよ緊張の結果発表へ。

まずは準優勝チームを表彰。「地下アイドルの守護神」というキャッチーなタイトルとアイドルに襲いかかる悪質なファンをサイリウムを投げて撃退するというコンセプトに会場は興味津々でした。このゲームはOculus Goを使用して、コントローラーを振りかざすとサイリウムを投げられるという仕組み。時間の都合上、一部実装が間に合わない部分があり、悔しさを見せていましたが、堂々の準優勝。結果発表の際には喜びの息もぴったりで、チームワークの良さが表れていました。

▼喜ぶ準優勝チーム

f:id:kenji-hanada:20180912163319j:plainそして、栄えある優勝は「Doki☆Doki☆Dungeon」というダンジョン探索ゲームを開発したチームでした!暗闇のダンジョンにそれぞれ特性を持った3色のライトを配置することで、迫り来る敵を避けながら宝を集めるという内容です。2日間でゲームとして仕上げたこと、Joy-Conを使用することで、振動によって敵や宝との距離を察知する機能まで実装し、見事優勝に選ばれました!

▼優勝チーム

f:id:kenji-hanada:20180912163322j:plain#最後に、運営側としての感想

2日間という非常に短期間ではありましたが、世の中をワクワクさせる様なゲーム開発に全力で取り組むみなさんのキラキラした姿を見れて感無量でした。中には今回開発したゲーム開発を継続したいという声もあり、非常に嬉しいです。是非、今回のインターンシップが一つの学びとなり、みなさんの次なる挑戦に繋がれば幸いです!

▼参加者のみなさん、本当にお疲れ様でした!

f:id:kenji-hanada:20180912163329j:plain

GLSL SandBoxで手軽にレイマーチングで遊ぼう

$
0
0

この記事は Akatsuki Advent Calendar 2018 - Adventar1日目の記事です。

はじめに

 こんにちは。クライアントエンジニアのRiyaaaaaです。

 皆さんは最近シェーダーを書いていますか? 私はあんまり書いていないですね。
 長らく触れないと、カンが鈍りがちになりますよね。なので、定期的に簡単なものでも書いたり作ったりすることは脳の体操にも効果的です。

 しかし、いざシェーダーを書こう!と思っても、ゲームエンジニアにとってはシェーダーはゲームやレンダラーと密接に結びついていて、手軽に何かを試すというのは難しかったりします。UnityやUnreal Engine4をわざわざ起動するのも億劫ですよね。
 そんな時、GLSL(OpenGL Shading Language)をWeb上でコーディングできるサービスがオススメです。有名なところだとGLSL Sandbox GalleryShadertoy BETAですね。
 
 今回はGLSL Sandbox Galleryを使った、リアルタイムアニメーションCG(デモシーン)の作成の流れを紹介しようと思います。
 この記事で皆さんが手軽にGLSLを触るようになり、レイマーチングをはじめとするリアルタイムレンダリングに興味を持っていただければ幸いです。

GLSL Sandboxの基本

 このサイトは、ピクセルシェーダーをリアルタイムにコーディングできるサイトです。こちら使い方は非常にシンプルで、GLSLを記述するとリアルタイムに変更が背景に反映されます。基本的な仕様は以下となります。
 
 ・gl_FragCoordに現在処理の対象となっているピクセルの座標が二次元ベクトルとして定義されます。 (定義域:(0, 0) ~ (xの解像度、yの解像度))
 ・gl_FragColorにそのピクセルの色をRGBAの4次元ベクトルで設定します。(値域:(0, 0, 0, 0) ~ (1, 1, 1, 1))

 試しに、gl_FragColorにRGB成分が全て0.5のベクトルを代入してみましょう。

// floatの精度を指定します
precision mediump float;

uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;

void main( void ) {
	gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
}

 GLSL Sandboxでは3つのuniform変数が使えます。timeは経過時間resolutionはウィンドウの解像度、mouseは現在マウスがフォーカスしている座標です。mouse、resolutionはgl_FragCoordと同じ定義域を持ちます。

 このコードでは座標(gl_FragCoord)に関わらず一様に(0.5, 0.5, 0.5)の色を代入しているので、画面は全て灰色に染まることでしょう。また、数字を変化させるとリアルタイムに背景の色が変わって行くのがわかると思います。

 次に、座標を色で表してみます。ここで、座標(gl_FragCoord)は(0, 0)からresolution.xyの値をとりますが、色は0から1で指定しなくてはならないので、座標を0 ~ 1で正規化しましょう。

// 省略void main( void ) {
        vec2 p = gl_FragCoord.xy / max(resolution.x, resolution.y);
	gl_FragColor = vec4(p, 0.0, 1.0);
}

 main関数を上記のように書き換えると、こんな画面が描画されることと思います。

f:id:riyaaaaasan:20181122142018p:plain

 R, G成分をX, Y座標に対応させているので、右に行けば行くほど赤く、上に行けば行くほど緑に近づいていきます。(縦横比が違う場合、厳密には短い方は0~1で正規化はできていません)

 GLSL Sandboxの基本的な解説は済んだので、本題のレイマーチングをこのGLSL Sandboxの上で実装してみましょう。

レイマーチングの基本

 レイマーチングとは、広義のレイトレーシングの一つです。カメラからレイを飛ばし、色を決定するところまでは同じですが、レイマーチングではレイの交差判定に距離関数というものを使います。距離関数とは、ある集合の中の二点の距離を定義する関数です。もっとも有名なのはユークリッド距離関数で、一般的な人間の感覚における「距離」を示す関数です。ユークリッド距離関数は距離関数の一つですが、ユークリッド距離関数 ≠ 距離関数であることには注意しましょう。

 つまり、レイマーチングは語弊を恐れずいうならば、全てのピクセルについて、シーン上に存在するオブジェクトを示す距離関数のどれかが0を返すまでレイを飛ばし(もしくは定められた計算数まで)、ヒットしたオブジェクトを描画する手法です。

f:id:riyaaaaasan:20181122160329p:plain

 実際に書いてみましょう。

// 球の距離函数float sphere_d(vec3 p) {
	const vec3 sphere_pos = vec3(0.0, 0.0, 3.0);
	constfloat r = 1.0;
	return length(p - sphere_pos) - r;
}

struct Ray {
	vec3 pos;
	vec3 dir;
};

void main( void ) {
   // 画面座標の正規化。中心が(0, 0)の方が都合がいいため-1 ~ 1で正規化する
	vec2 pos = (gl_FragCoord.xy * 2.0 - resolution) / max(resolution.x, resolution.y);
	
        // カメラの位置。中心から後方にあるイメージ
	vec3 camera_pos = vec3(0.0, 0.0, -4.0);
        // カメラの上方向の姿勢を定めるベクトル この場合水平
	vec3 camera_up = normalize(vec3(0.0, 1.0, 0.0));
        //  カメラの向いている方向 
	vec3 camera_dir = normalize(vec3(0.0, 0.0, 1.0));
        // camera_upとcamera_dirの外積から定まるカメラの横方向のベクトル 
	vec3 camera_side = normalize(cross(camera_up, camera_dir));
	
        // レイの位置、飛ぶ方向を定義する
	Ray ray;
	ray.pos = camera_pos;
	ray.dir = pos.x * camera_side + pos.y * camera_up + camera_dir;
	
	float t = 0.0, d;
        // レイを飛ばす (計算回数は最大64回まで)for (int i = 0; i < 64; i++) {
		d = sphere_d(ray.pos);
                // ヒットしたif (d < 0.001) {
			break;
		}
                // 次のレイは最小距離d * ray.dirの分だけ進める(効率化)
		t += d;
		ray.pos = camera_pos + t * ray.dir;
	}

	if (d < 0.001) {
                // ヒットしていれば白
		gl_FragColor = vec4(1);	
	} else {
		gl_FragColor = vec4(0);	
	}
}


 スフィア一個を配置し、カメラを画面後方に設定しました。位置関係を図で表すと以下のような感じです。


f:id:riyaaaaasan:20181128155827p:plain


 そして、以下のように描画されます。
 

f:id:riyaaaaasan:20181122163232p:plain


 これで最も基本的なレイマーチング は実装できました。しかし、せっかく3Dでやっているのに平べったく見えてしまいます。
 次はライティングをしてみましょう。

レイマーチングにおけるライティング表現

 今回はディレクショナルライトによるライティングを行います。必要なのは、光源ベクトルと、ライティング対象の法線ベクトルです。
 一般的な3Dのレンダリングにおいては、法線ベクトルは頂点データから与えられますが、レイマーチング の場合は距離函数による衝突判定を行っているため、同じの手法は使えません。
 ここで、数学的なアプローチにより、「陰関数の勾配ベクトルは法線ベクトルとなる」という性質を使って、法線ベクトルを求めてみたいと思います。
 勾配ベクトルとは、各成分の偏微分を並べたベクトルを指します。陰関数とは \boldsymbol{R}(x, y, z....) = 0の形で表される関数のことを指し、距離函数も陰関数表示の一つです。

 つまり、距離函数を使って任意の座標の法線ベクトルを求めるためには
  \boldsymbol{t} = (\frac{∂f}{∂x}, \frac{∂f}{∂y}, \frac{∂f}{∂z})を求める必要があります。xの偏微分の定義は以下。

 \frac{∂f(x, y, z)}{∂x} := \lim_{h \to 0}\frac{∂f(x + h, y, z) - ∂f(x, y, z)}{h}
 y, zの偏微分についても同様のことが言えます。

 数値計算的に求めてみましょう。

vec3 sphere_normal(vec3 pos) {
  float delta = 0.001;
  return normalize(vec3(
    sphere_d(pos + vec3(delta, 0.0, 0.0)) - sphere_d(pos),
    sphere_d(pos + vec3(0.0, delta, 0.0)) - sphere_d(pos),
    sphere_d(pos + vec3(0.0, 0.0, delta)) - sphere_d(pos)
  ));
}

 これで法線ベクトルを求めることができます。
 次に光源ベクトルをLとして、頂点の輝度を求めましょう。ここではシンプルにランバート反射を使います。

vec3 L = vec3(0.0, 0.0, 1.0); // 光源ベクトル
vec3 N = sphere_normal(ray.pos); // 法線ベクトル
vec3 LColor = vec3(1.0, 1.0, 1.0); // 光の色
vec3 I = dot(N, L) * LColor; // 輝度

 これらを先ほどの実装に組み込むと、このようにライティングされます。

f:id:riyaaaaasan:20181128164303p:plain

 ソースコードが長くなってしまったので、フルバージョンはgistにアップしています。
raymarching-sphere-lighting · GitHub

 光源ベクトルが(0.0, 0.0, 1.0)なので、球の正面に光を当てていることになりますね。光の方向を変えてみると光の当たり方が変わります。(必ずその際は光源ベクトルを正規化をしてください)

 他にも、距離函数にmod関数(剰余)をかますことで、レイの値域を制限し、あたかもオブジェクトが複製されているように見せかけるテクニックがあります。

float sphere_d(vec3 p) {
	constfloat r = 1.0;
	return length(mod(p, 4.0) - 2.0) - r;
}

 f:id:riyaaaaasan:20181128174155p:plain

 さて、ここまで基本を抑えてしまえばあとはなんでもありです。
 超かっこいいエフェクト(ブルームや走査線など)を好き放題追加するのもありですし、面白い距離函数を実装してみるのもいいかもしれません。

 最後に、パーリンノイズを使ったレイマーチング によるテライン描画をやってみましょう。

パーリンノイズを使ったレイマーチングによるテライン表現

 パーリンノイズは、テクスチャの表現によく使われる、とても自然に感じる(?)擬似乱数を生成するアルゴリズムです。話すと長くなるのでここでは端折って、解説や実装を引用したいと思います。

The Book of Shaders: Noise

 今回はこの中にあるパーリンノイズをさらに改良したシンプレックスノイズというのを使いましょう。このシンプレックスノイズを、距離函数として応用してレイマーチングに使用します。

 試しにまず、このシンプレックスノイズをテクスチャとして描画してみましょう。

void main( void ) {
	vec2 pos = (gl_FragCoord.xy * 2.0 - resolution) / max(resolution.x, resolution.y);
        // snoiseは上記文献で示されているシンプレックスノイズ関数float c = snoise(pos * 5.0);
        gl_FragColor = vec4(c, c, c, 1.0);	
}

f:id:riyaaaaasan:20181128175015p:plain

 この時、シンプレックスノイズ関数は、 y = f(x, z)という二変数関数で示される曲面であると解釈できます。(数学でよく表す空間と、GLSLの空間ではzとyが逆転していることに注意してください)
 つまり、レイの座標を(Rx, Ry, Rz)とすると、 f(Rx, Rz) - Ry = 0を満たすとき、レイはこのシンプレックスノイズ曲面上にある(衝突した)と考えることができます!

 

float map(vec3 v) {
        // 地面のオフセットconstfloat GROUND_BASE = 1.2;
	return v.y - snoise(v.xz * .4) + GROUND_BASE;
}

vec3 map_normal(vec3 v) {
	float delta = 0.01;
	return normalize(vec3(map(v + vec3(delta, 0.0, 0.0)) - map(v), 
			      map(v + vec3(0.0, delta, 0.0)) - map(v), 
			      map(v + vec3(0.0, 0.0, delta)) - map(v)));
}

 謎のマジックナンバーが出てきていますが、これは自由に変えることが可能なパラメータです。試しにいじってみるのもいいでしょう。

 さて、このmap関数をスフィアの距離函数の代わりに使い描画してみると...
 raymarching-terrain-sample · GitHub


 f:id:riyaaaaasan:20181128180017p:plain

 見事テラインが描画されました! 今回は、カメラの座標にtimeを加えているので、リアルタイムにテラインが動いていくのがわかると思います。

おわりに

 レイマーチングは解説した通りレイトレーシングの交差判定に距離函数を使うだけのシンプルなアルゴリズムです。一方で、その応用範囲は無限大です。距離函数はその特性上、幾何的なオブジェクトの描画に向いていますが、組み合わせや微調整を繰り返すことで、生き物のようなオブジェクトを描画することだって可能です。ボリュームレンダリングという3次元的な広がりのあるデータの描画に応用して雲などを描画することもできます(こちらは、実際に多くのゲームへの採用例があります)。
 他にも、パーリンノイズによるテライン表現を応用すると、グランドキャニオンのような光景や、リアルな水面でさえも描画することができます。
 このように、レイマーチング等を用いたデモシーンは、様々な工夫や自分の考えた最強の関数などを好き放題盛り込んで一つの作品を作る面白い分野です。ぜひ遊んで、あなただけの作品を作ってみてください。

 
 
 

Git のベースブランチを記録する

$
0
0

この記事は Akatsuki Advent Calendar 2018の 8 日目の記事です。

このブログでは初めましてになります。id:thincaです。今日は Vimの話…ではなく、お仕事用にごにょごにょしている Git の設定の話をしようかと思います。

背景

私のいるチームでは複数バージョン平行開発が行われており、それもあいまって Git リポジトリには各バージョンや stagingmasterなど様々なブランチが存在しています。

そしてそれぞれのブランチから作業用のブランチを作るわけですが、Git では「あるブランチがどのブランチから派生したのか」ということは記録されていません*1。Git の構造を考えると記録されていないのは当然なのですが、これを記録するようにすると、様々な場面で活用できます。そこで私が普段している工夫を紹介したいと思います。

Git の alias 機能

この工夫のために、Git に大量の alias を定義しています。今回の話はほぼ、この alias 集の紹介になります。

各 alias は別の alias に依存しているものもあるので、順を追って紹介していきます。

以後出てくる xxx = yyyの形式の行は、Git の config ファイル内での記述になります。

現在のブランチを取得する

current-branch = symbolic-ref --short HEAD

ありそうでない、現在のブランチを表示するコマンドです。様々なシーンで使うので、最初に紹介しておきます。

ブランチ元のブランチを記録/表示する

base-branch = !git config "branch.$(git current-branch).base"

本稿で伝えたい工夫のコアの部分になります。git configを使って、各ブランチの baseと言う名前の項目にブランチ元のブランチ(=base branch)を記録できるようにします。 以下のような感じで使います。

$ git current-branch
new-feature

# ベースブランチを master に設定する
$ git base-branch master

# ベースブランチを表示する
$ git base-branch
master

$

とは言っても、実際にこのコマンドを直接使うことはあまりありません。他の alias から利用する場合が多いです。

ちなみに、こうして記録した内容は .git/configファイル内に記録されます。ブランチを消したら設定も一緒に消えるので、ゴミが残ったりはしません。

[branch "new-feature"]base = master

作業用ブランチを作成する

現在のブランチから作業用ブランチを作成する際、私はよく git cobという alias で行っていました。これは最初は git checkout -bの略だったのですが、base-branch を導入した今では以下のようになっています。

cob = "!f() { \  b=$(git current-branch) && \  git checkout -b \"${1}\"&& \  git base-branch \"${b}\"; \}; f"

alias で引数を受け取りつつアレコレしたい場合のイディオムの 1 つとして、関数を作ってこれを実行しています。他にも方法はありますが、私はこの方法をよく使います。

これで、git cob new-featureを実行すると、new-featureブランチのベースブランチとして元いたブランチが記録されるようになりました。

分岐地点のコミットを得る

せっかく記録をしても活用しないと意味がありません。そのためにも、追加の補助機能を用意します。

base-commit = !git merge-base origin/$(git base-branch) HEAD
     -o--o  <- new-feature
    /
o--o--o--o  <- master
   ^
   ここを得る

こんな感じで、現在のブランチを切った根本に当たるコミットの sha1値を得るコマンドになります。これがあると、以下のようなことができます。

現在のブランチ内だけのログを表示

普通にログを表示すると、辿れるだけ際限なく表示されます。今のブランチでは何をやったのかに注目したい場合、その部分だけ表示できると便利です。

fl = !git log $(git base-commit)..HEAD --reverse

ログの表示の仕方は好みがあると思うので、お好みの感じにするとよさそうです。alias の名前も短くて覚えやすいのを付ければよいかと思います。

現在のブランチで変更したファイルを表示

先ほどと同じようなやつですね。これは diff でできます。

bf = !git diff --name-only "$(git base-commit)..HEAD"

変更したファイルだけ、まとめて lint にかけたりする際に便利です。

$ rubocop $(git bf)

特定のバージョンブランチから派生した作業用ブランチ一覧を表示する

あちこちのバージョンで気まぐれに始めては途中で止まっているブランチがあるため、通常の git branchによるブランチ一覧だとどのブランチがどのバージョン上で作業していたものなのかがわかりづらくなってしまいます。そこで、今いる(あるいは指定した)ブランチから作られたブランチの一覧を表示できるようにします。

features = "!f() { \  git branch | \    cut -c3- | \    while read b; \      do echo \"$(git config \"branch.${b}.base\") -> ${b}\"; \    done | \    grep -v '^ -> ' | \    grep \"^${1:-$(git current-branch)} ->\" | \    sort; \}; f"

こういう感じで結果が見れます。

$ git features master
master -> feature-a
master -> feature-b

$

rebase する

当然 rebase も簡単にできます。

rbu = !git rebase "origin/$(git base-branch)"
     -o--o  <- new-feature
    /
o--o--o--o  <- master

 |
 v

           o--o  <- new-feature
          /
o--o--o--o  <- master

fetch によって origin が伸びている場合が多いので、origin のブランチの先頭に対して rebase するようにしています。 実は git base-branchでもこっそり origin を見ていました。これは今回のように rebase することがあるためです。

base を移動する

version-aブランチからブランチを作ってやってる作業を version-bに入れることになった!となったら、rebase を利用すればサクッと移動できます。

move-base = "!f() { \  [[ -n $1 ]] && \  git rebase --onto $1 $(git base-branch) && \  git base-branch $1; \}; f"

git move-base version-bversion-bに移動できます。

現在の差分をブランチ中の特定のコミットに混ぜ込む

ブランチで作業中に、途中で typoを入れ込んだことに気付いた時、新たに Fix typoなんてコミットを積む人はいないと思います。後から見て履歴がわかりやすくなるように、最初から typoを入れないように履歴を修正するでしょう。となったら rebase による履歴改変の出番となるわけですが、普通にやると意外に面倒です。これもサクッとできるようにしています。

まずは混ぜ込む先のコミットを簡単に選べるようにしたい、ということで以下は fzfを使ってコミットを選択するコマンド。コミットの範囲を引数に渡します。previewgit showを使ってコミットの中身を見つつ選択できるようにしてあります。

select-commit = "!f() { \  git log --oneline ${1} | \    fzf --preview='git show --color {1}' | \    cut -b 1-7; \}; f"

続いて現在の差分を、この git select-commitを使って選択したコミットに対する fixup コミット*2としてコミットするコマンド(わかりづらい)が以下。

fixcommit = "!f() { \  git commit --fixup=\"$(\    git select-commit \"${1:-$(git base-commit)}..HEAD\"\  )\"; \}; f"

git base-commitを使って適切な範囲のみを候補として表示するようにしています。

さて、fixup コミットを作ったので、これを適用します。適用するためのコマンドが以下。

fixup = !git -c core.editor=true rebase -i --autosquash $(git base-commit)

base を記録しているおかげで、rebase を機械的に実行できます。--autosquashを付ければ最初から fixup 済みの状態でエディタが開くので、編集する必要もありません。編集しなくてもよいので、エディタとして trueコマンドを指定して、すぐに閉じています。これで fixup を適用できます。

ここまで来たらまとめてやってしまいたいので、まとめてやるコマンドを用意しています。

fix = "!f() { \  git fixcommit ${1} && \  git fixup; \}; f"

つまり、typo直したい!となったら、

  1. 直して git add
  2. git fix
  3. fzf が起動するので対象コミットを選択
  4. 混ぜ込み完了

となります。簡単ですね。

GitHubの PR 作成ページを開く

近ごろの GitHubはとても便利なので、新規ブランチを push すると「このページにアクセスすれば PR 作れるよ!」と教えてくれます。*3

remote: Create a pull request for 'new-feature' on GitHub by visiting:
remote:      https://github.com/aktsk/awesome-product/pull/new/new-feature

しかし、いざこのページにアクセスすると base はデフォルトブランチとしてページが開きます。デフォルトブランチと開発ブランチでは差が大きくなっていることは珍しくなく、差分の生成のために GitHubを開くのが重くなります。こんなページは開きたくない。

そこで、直接!目的の base に対して PR が作れるページをブラウザで開くコマンドです。ブラウザを開くために openを使っているので、MacOS専用です。

gh-repo = "!git remote get-url origin | sed 's/.*:\\(.*\\)\\.git/\\1/'"mkpr = "!open https://github.com/$(git gh-repo)/compare/$(git base-branch)...$(git current-branch)?expand=1"

まとめ

今回は、Git にベースブランチを記録することで様々な作業を効率化する例を紹介しました。Git の alias の設定は config ファイル 1 つで管理できるため、環境間での取り回しがやりやすいです。その分複雑なことをしようとするとメンテナンスが難しくなってしまいますが、その点は適切に改行を入れたり、コマンドを分割することで緩和してみました。

小さな工夫で作業を効率化できることは多いので、不便に感じたら積極的に効率化して行きましょう。

*1:単純なリポジトリであればある程度推察できる場合がありますが、複雑になると失敗するので確実性がありません。

*2:fixup コミットについてはこちらの記事等が参考になります。

*3:この URL は例なので実在しません。

GAE/Go & CircleCI でカナリアリリースをする

$
0
0

この記事はAkatsuki Advent Calendar 2018の12日目の記事です。 前回は hayamaruさんの、知覚メカニズムと網膜投影でした。

はじめに

継続的デリバリーという文脈で、素早く、安全にデプロイする手法について、近年多くの記事を見かけます。

例えば、カナリアのおかげで命拾い : CRE が現場で学んだことカナリアリリースについて詳しく触れられています。このアイデアは「たとえテスト環境で十分な検証をしたとしても、本番環境で問題が発生しないということを保証するのは難しいので、少しづつトラフィックを移動して問題があったらすぐにロールバックをしよう」というものです。

上記記事中に紹介されているKayentaといったツールを使ってカナリア分析を行い、自動的にカナリアリリースするというのも良いですが、人間による承認を元にデプロイするならもう少しコストの低い方法で良さそうです。

この記事では、CircleCIのワークフローを使って、承認を元にGoogle App Engineトラフィックを移動するという形で、カナリアリリースを実現します。

サンプルアプリケーション

この記事のサンプルコードはcsouls/gae_go111-deploy_sampleに置いています。 また、サンプルプロジェクト名をproject-nameとしているので、適宜読み替えてください。

(このコードは、Google Cloud Platformのリポジトリで公開されているGAEのサンプル、go11x/warmupからコピーして修正したものです。)

このアプリケーションは、初期処理が完了した後に、どれだけ時間が経過しているか?というのを表示するための実装と、ウォームアップリクエストを受け付けるための実装がされています。

GAEでのデプロイ

Google App Engineへのデプロイはとても簡単です。 Cloud SDKをインストールして、GCPコンソールから新しいプロジェクトを作り、以下のコマンドを実行したあとにデプロイするリージョンや確認に応答するだけで、アプリケーションのデプロイができてしまいます。

gcloud app deploy --project=project-name

結果

You are creating an app for project [project-name].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.

Please choose the region where you want your App Engine application
located:

 [1] asia-east2    (supports standard and flexible)
 [2] asia-northeast1 (supports standard and flexible)
 [3] asia-south1   (supports standard and flexible)
 [4] australia-southeast1 (supports standard and flexible)
 [5] europe-west   (supports standard and flexible)
 [6] europe-west2  (supports standard and flexible)
 [7] europe-west3  (supports standard and flexible)
 [8] northamerica-northeast1 (supports standard and flexible)
 [9] southamerica-east1 (supports standard and flexible)
 [10] us-central    (supports standard and flexible)
 [11] us-east1      (supports standard and flexible)
 [12] us-east4      (supports standard and flexible)
 [13] us-west2      (supports standard and flexible)
 [14] cancel
Please enter your numeric choice:  2

Creating App Engine application in project [project-name] and region [asia-northeast1]....done.
Services to deploy:

descriptor:      [/Users/y.tanaka/src/sandbox/gae_go111_deploy_sample/app.yaml]
source:          [/Users/y.tanaka/src/sandbox/gae_go111_deploy_sample]
target project:  [project-name]
target service:  [default]
target version:  [20181212t155052]
target url:      [http://project-name.appspot.com]


Do you want to continue (Y/n)?  y
... deploy log ...

Deployed service [default] to [http://project-name.appspot.com]

デプロイの中身

gcloud app deployを実行することで何が行われているかは、コマンドを実行したあとの標準出力に表示されています。

Services to deploy:

descriptor:      [/Users/y.tanaka/src/sandbox/gae_go111_deploy_sample/app.yaml]
source:          [/Users/y.tanaka/src/sandbox/gae_go111_deploy_sample]
target project:  [project-name]
target service:  [default]
target version:  [20181212t160030]
target url:      [http://project-name.appspot.com]

この例では、gae_go111_deploy_sample/app.yamlという App Engineの設定を元に、gae_go111_deploy_sampleをソースとして、project-nameというプロジェクトのdefaultというサービスの、バージョン20181212t160030を作成し、そのバージョンでサービスのトラフィックを100%処理する設定にした上で、http://project-name.appspot.comというURLで公開する、という内容となっています。

gcloud app deployに、--no-promoteというフラグを指定すると、「新しいバージョンは作るが、トラフィックは移動しない」という動作になります。

デプロイのデフォルト動作

gcloud app browse --project=project-nameを実行してブラウザでアクセスしてみると、実装の通りインスタンス起動からの経過時間が表示されます。表示されている時間は約50msということなので、このインスタンスに対する最初のアクセスであることが分かります。 f:id:csouls:20181212231737p:plain

再度アクセスすると、初回アクセスからの経過時間が表示され、同じインスタンスで要求を受けていることが分かります。 f:id:csouls:20181212231949p:plain

GAEのコンソール、Logging ->ログから、Stackdriver Logging に自動的に記録されたアクセスログが確認できます。レイテンシの内容を確認すると、初回アクセスの応答は50msではなく、775msかかっているようです。体験としてもこれくらい待たされています。

また、トレースがサンプリングされている場合は、レイテンシをクリックすることでトレースの詳細を確認することができます。

f:id:csouls:20181212232051p:plain

どうやら、サービスのデプロイにより新しいプロセスが起動され、loading requestが発生しているようです。 f:id:csouls:20181212232159p:plain

このサービスではapp.yamlに以下の記載をしているので、warmup requestsが有効になっていますが、単純に gcloud app deployをしても、warmupが実行されない様です。

inbound_services:
  - warmup

handlers:
  - url: /_ah/warmup
    script: auto
    login: admin

本番環境でデプロイの運用をする場合は、この動作についても何らかの対処が必要でしょう。

CircleCIの設定

デフォルトの動作を踏まえ、warmupを有効にする形で GAE & CircleCIでのカナリアリリースを設定していきます。

サービスアカウントの設定

この手順に従い、circleci/gcp-cli@1.0.1を使う前提で、サービスアカウントの設定をします。気をつけることは以下です。

  1. GAE コンソールから、App Engine Admin APIを有効にする必要があります。
  2. GAEでデプロイをさせるサービスアカウントには、「App Engine デプロイ担当者」「App Engine サービス管理者」「Cloud Build サービス アカウント」「ストレージのオブジェクト管理者」の権限が必要です。
  3. CircleCIのプロジェクト設定 -> BUILD SETTINGS -> Environment Variables -> Add Variable から、下表の環境変数を設定します。
環境変数内容
GCLOUD_SERVICE_KEYbase64 <service-account-json>.jsonの結果
GOOGLE_PROJECT_IDGCPプロジェクトのID
GOOGLE_COMPUTE_ZONE動作させるZone。空白を設定すると、Zone指定なし。※後続の項で説明するcircleci/gcp-cliを使う場合、環境変数の定義は必ずしておかなければいけない。

gcp-cli/initializestepのパラメータで環境変数名を指定することができるので、一つのリポジトリに対して複数の環境があっても大丈夫です。

CircleCIの設定ファイル

リポジトリ直下の.circleci/config.ymlに、以下の様に記述します。

version: 2.1
orbs:
  gcp-cli: circleci/gcp-cli@1.0.1
executors:
  golang:
    docker:
    - image: circleci/golang:1.11
  gcloud:
    docker:
    - image: google/cloud-sdk:latest

jobs:
  test:
    executor: golang
    steps:
      - checkout
      - restore_cache:
          keys:
          - go-mod-v1-{{ checksum "go.sum" }}
      - run:
          name: build
          command: go build
      - run:
          name: test
          command: go test

  deploy:
    executor: gcloud
    steps:
      - checkout
      - gcp-cli/initialize
      - run: gcloud app deploy --no-promote --version $CIRCLE_SHA1 --quiet

  set-traffic:
    parameters:
      before-traffic:
        type: string
        default: "0.99"
      after-traffic:
        type: string
        default: "0.01"
    executor: gcloud
    steps:
    - checkout
    - gcp-cli/initialize
    - run: |
        BEFORE_VERSION="$(gcloud app versions list --service=${GAE_SERVICE} --filter='traffic_split>0.5' --format='value(id)')"
        gcloud app services set-traffic --splits ${BEFORE_VERSION}=<< parameters.before-traffic >>,${CIRCLE_SHA1}=<< parameters.after-traffic >> --split-by=random --quiet

  promote:
    executor: gcloud
    steps:
    - checkout
    - gcp-cli/initialize
    - run: gcloud app services set-traffic --splits ${CIRCLE_SHA1}=1 --split-by=random --quiet --migrate

workflows:
  version: 2
  test_and_deploy:
    jobs:
      - test
      - deploy:
          requires:
          - test
          filters:
            branches:
              only:
                - master
      - hold-canary:
          type: approval
          requires:
          - deploy
      - set-traffic:
          name: canary
          requires:
          - hold-canary
          before-traffic: "0.01"
          after-traffic: "0.95"
      - hold-promote:
          type: approval
          requires:
          - canary
      - promote:
          requires:
          - hold-promote

以下、ポイントを解説します。

orbs

orbとは、CircleCI 2.1から追加された、設定をパッケージとして共有可能にするものです。 今回はGCPCLIを使うので、その初期設定でcircleci/gcp-cli@1.0.1を利用しています。

orbs:
  gcp-cli: circleci/gcp-cli@1.0.1

...snip...

jobs:
    steps:
      - gcp-cli/initialize

deploy ジョブ

新しいバージョンを作るジョブです。 $CIRCLE_SHA1をバージョン名として指定しています。これで、CircleCIから操作するバージョンを特定するのが簡単になります。

  deploy:
    executor: gcloud
    steps:
      - checkout
      - gcp-cli/initialize
      - run: gcloud app deploy --no-promote --version $CIRCLE_SHA1 --quiet

set-traffic ジョブ

トラフィックの分割をするジョブです。 トラフィックの50%以上を割り当てられているバージョンを前のバージョンだと判断しています。

  set-traffic:
    parameters:
      before-traffic:
        type: string
        default: "0.99"
      after-traffic:
        type: string
        default: "0.01"
    executor: gcloud
    steps:
    - checkout
    - gcp-cli/initialize
    - run: |
        BEFORE_VERSION="$(gcloud app versions list --service=${GAE_SERVICE} --filter='traffic_split>0.5' --format='value(id)')"
        gcloud app services set-traffic --splits ${BEFORE_VERSION}=<< parameters.before-traffic >>,${CIRCLE_SHA1}=<< parameters.after-traffic >> --split-by=random --quiet

promote ジョブ

トラフィックを新しいバージョンに100%移行するジョブです。 --migrateオプションを付けることで、トラフィックを徐々に移行してくれます。 また、Warmup処理を実行してくれます。

promote:
  executor: gcloud
  steps:
  - checkout
  - gcp-cli/initialize
  - run: gcloud app services set-traffic --splits ${CIRCLE_SHA1}=1 --split-by=random --quiet --migrate

ワークフロー

test -> deploy -> hold-canary -> set-traffic(canary) -> hold-promote -> promoteの順に並ぶように、requiresで設定しています。

また、deployはmasterブランチでのみ実行されるので、それ以外のブランチではtestだけが実行されます。

hold-canary, hold-promote では type: approvalで設定しているため、ここで人間の承認が入るという設定になっています。

workflows:
  version: 2
  test_and_deploy:
    jobs:
      - test
      - deploy:
          requires:
          - test
          filters:
            branches:
              only:
                - master
      - hold-canary:
          type: approval
          requires:
          - deploy
      - set-traffic:
          name: canary
          requires:
          - hold-canary
          before-traffic: "0.01"
          after-traffic: "0.95"
      - hold-promote:
          type: approval
          requires:
          - canary
      - promote:
          requires:
          - hold-promote

結果

masterブランチにpushしたあとに、deployジョブ(新バージョンの作成)が完了した状態です。 type: approvalのワークフロー定義により、hold-canaryで止まっていることが分かります。 f:id:csouls:20181212233504p:plain

hold-canaryを承認し、canaryジョブまで実行された結果です。 ワークフローの承認者がアイコンで表示されていること、次のhold-promoteで止まっていることが分かります。このジョブの前に、承認待ちのワークフローへのリンクをSlackへ通知するのも良いでしょう。 f:id:csouls:20181212233819p:plain

トラフィックの割当も新バージョンに1%, 旧バージョンに99%となっています。 この状態でアプリケーションエラーが発生していないか、新バージョンのレイテンシやその他メトリクスに悪化したものがないか、を確認することができます。f:id:csouls:20181212233950p:plain

承認する際は、このようなダイアログが表示されるので、間違えてクリックしてしまっても大丈夫です。 f:id:csouls:20181212233236p:plain

--migrateオプションを付けたことで、トラフィックが徐々に移行されていることが分かります。 f:id:csouls:20181212233247p:plain

Stackdriver loggingからログをみても、warmup リクエストが処理されており、2回目の応答は4ms程度で返せていることが分かります。 f:id:csouls:20181212233311p:plain

開発者の数が50名を超えるような大規模なプロジェクトになると、冒頭で紹介したKayentaのようなツールが必要になると思いますが、小規模であればこのCircleCIのワークフローを使った人間による承認でも十分なことが多いと思います。

設定にコストをかけずに、GAEのカナリアリリースを実現する手段として、CircleCIと組み合わせるアイデアを覚えておくと役に立つことがあるかもしれません。

Viewing all 223 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>