まるまるこふこふ

数々の次元が崩壊し、全ての生命が塵と化すのを見てきた。私ほどの闇の心の持ち主でも、そこには何の喜びも無かった。

2018年振り返り

過去ログ
2017年振り返り - まるまるこふこふ
2016年振り返り - まるまるこふこふ

目次

リードエンジニア

2018年3月~現在まで、エンジニア3名規模のチームでリードエンジニアをやっていました。 弊社の開発基盤チームにて、各ゲームタイトルで使われる横断プロダクトを 0 -> 1で開発しています。

主に以下のことに意思決定を行い、責任を追ってました。

  • システム開発の進め方、採用技術
  • 成果物(プロダクト)の方向性
  • チームメンバーのアウトプット向上
  • プロダクトの採用チームとの社内調整

それに加えて1メンバーとして、主に技術的な難易度の高いところで、手を動かして 開発もやっておりました。

メンバーに恵まれたおかげか、特に問題なく順調に進んでいるように思います。

個人的な振り返りとしては、時期によって、間接業務が多くて、そうした業務は明確なゴールがなく、 達成感がなくて大変だった...というところです。

社内でのゲーム開発 立ち上げ

2018年の目標として、新しい取り組みとして、お会社でゲームの企画書出してみようかなぁと考えていたのですが、 実際に機会があり、自分の起案でゲームを開発しておりました。

期初では主に、ゲームの企画書を書き、またその後はプロトタイプを作りながら、 面白い面白くない、ここはこうしたほうがみたいなことを検証していました。

個人制作ゲーム

探索ホラーゲーム制作

2019年05月に完成版予定です。元々は同人ゲームでありましたが、パブリッシャーにお声掛け頂き、 PS4/Nintendo Switch/Steam でリリース予定となりました。

“PAX WEST”に“UNTIES”のブース出展が決定! 『The Good Life』のパブリッシャーとして参加することも明らかに - ファミ通.com (記事の中盤くらい)

またそれに伴い PAX WEST などの海外イベントにも出展させていただきました。 (ゲームのローカライズを初めてやった)

特に印象的だったのは、ニコ生放送内で、東方Project の原作者 ZUN さんとお話させていただいたことでしょうか。

f:id:sairoutine:20190101233308p:plain

5名チームで制作をしております。ほとんどのメンバーがゲームを作ることが未経験で、また初めて一緒に 作業することから始まりましたが、評価される作品が作れていることを嬉しく思います。

自分はチーム内で、以下のことに意思決定を行い、責任を追ってました。

  • プロデュース
    • パブリッシャーへのアプローチ・契約交渉
    • パブリッシャーとのコミュニケーション
  • ディレクション
    • 各職種のワークフロー構築
    • チームのスケジュール管理
    • スケジュール上の課題のためのメンバー間調整
  • マネジメント
    • メンバーのケア
    • 各個人が自走できるチームのルール・雰囲気作り
  • エンジニアリング
    • ゲーム開発(プログラミング)

メンバーそれぞれの得手・不得手が激しく、また少人数チームでリソースが少ないため、 メンバー1人の不得手のためにプロジェクトが危機に陥ることもあり、 マネジメントに相当力を割いていたなと振り返れば思います。

不得手はカバーしつつ、得手を活かせるチーム体制にできればいいなと思ってます。 (口で言うのは簡単...)

自分はロジカルに考えたり、意思決定するタイプであり、それを人にも求めるクセがあったのですが、 このプロジェクトを通して、人の感情に配慮するようになったなと成長がありました。 例えばですが、人が心を動かされるような目標を口に出して言ったりするの、大切だと思います。

RPGアツマール向け ミニゲーム

進行中のゲーム1件です。12月リリースを目標に、9月末にプロトタイプを開発し、 イラストを他の方にお願いしたのですが、結局11月12月と時間が取れず、リリースできず仕舞い。

イラストをチーム以外の人にお願いする場合、コミュニケーションが薄くなりがちなので、 事前にイラストの要件などを明確に定めてから、発注するのですが、 今回は、イメージ画像などを使いつつ、要望を相手に伝えられたので、そこは成長した点かなと思っています。

(以前は要件などがあまり定まらないまま相手にお願いして、相手任せにしてしまって困らせることがあった)

2Dアクションゲーム

進行中の探索ホラーゲーム制作が終わったら、次にと考えて種まきしていた案件です。 企画書を書き、シナリオを書いてもらったところで、pend になっています。

OSSコントリビュート

gin, noms といった golang プロダクトにコントリビュートしていました。 コード自体は1~2日で書けて、あとはPR上でコミュニケーションするのですが、 マージされると手軽に達成感が得られるので、お仕事で進捗出ないときにしていた記憶があります。

思想/哲学/歴史の本を読む

2018年の目標の一つでした。ジャレド・ダイアモンド、ユヴァル・ノア・ハラリ辺りの本を読んでいました。 歴史の中での現代や、あるいは自分が何をすべきかについて、解像度が上がり、 またこういった本を読む習慣がついたので、目標達成としています。

この1年考えた中で、自分の中長期のビジョンは以下です。

◆ ビジョン(中期)
サブカルチャー界隈のクリエイターと消費者のマスの代表となり、彼らがより良い人生を歩めることに寄与する。

◆ ビジョン(長期)
人類の過去の延長線から、現代の在り方(人々の思想・生活様式)を変え、コンテンツ享受を通して、人類の未来に貢献する。

サブカルチャー(特にオタクコンテンツ)が好きなのですが、経済、政治、教育、文化における それらの立ち位置は低いままです。それらに関わるクリエイターや消費者も、同様の立ち位置になってしまうことがあり、 それを課題に思っています。

まず、クリエイター及び消費者の向上に務めること、またその延長線上で、人類におけるコンテンツの価値向上に務めることが大切だと思っています。何十年かかるかわからないし、できるかどうかもわかりませんが、人生かけるに値するビジョンなのかなと思います。

データベース本の輪読

社内で Designing Data-Intensive Applications (DDIA)の輪読会があったので、参加してました。 邦訳がないので、英語の本なのですが、だいたい 2.5 ヶ月くらいかけて読みました。

2018年の目標にしたけど達成できなかったこと

ゲーム制作

2018年の目標として、完成版のリリース2つ。進行中のゲーム2つくらい進めたいなと思っていたのですが、 実際は、体験版のリリースが1作、進行中のゲームが 2作となりました。

これは、探索ホラーゲームのコンシューマーゲーム化に伴い、 この1作を最注力していく方針に変更したためです。

そのような中でも進行中2作を作れたのは良かったと思います。 これは元々定めていた目標が今の自分では高すぎる目標非だったことが、実際に取り組んでみてわかりました。

Web サービス

ゲーム制作ツールの Web サービスを作っていたのですが、リリースをやめることにしました。

反省すると、以下の理由があります。

  • プロダクトについて自分が納得できるゴールイメージが持てなかったこと
  • リリースして、自分の期待値通りに、利用者が幸せになるイメージが持てなかったこと

Webサービスに関して、自分の期待値と、実際のスキルにギャップがあり、 それを受け入れられていないように思います。(スキルについては、技術面よりサービス設計面)

今後 Webサービスを作る際は、自分の期待値を下げて、継続的に作り続けることで 実際のスキルを上げていく必要があります。

OSSプロダクト

リアルタイム通信サーバーを書いて OSS にしたかったのですが、ほとんど取り組めませんでした。 これも時間が割けなかった目標の一つです。

3D の勉強

WebGL 周りのおさらいをしていましたが、実際にゲームを作れるようになるまでは至らず...。 単純に時間が足りなかった系ですね。

自分がどう変わったか

コードを書くこと、人間関係をやることにフォーカスし、アウトプットに全時間を投入するということを、どこまでできるかを試していた年でした。

睡眠時間8時間、お会社の仕事10時間、生活2時間と仮定すると、 平日4時間、休日14時間はサブプロジェクトに時間当てられるし、それで1人月あるよねって思想で生きてました。 (振り返ると、実際はインプットに結構時間割いてたので、1人月もアウトプットしていない)

結果としてアウトプット量がどうなったのか、2017年振り返りと比べてみると、以下のことがわかりました。

  • 達成できた目標の数は実は増えていない
  • 達成できた目標の質は、どれも向上している(より高い成果になっている)
  • 目標にしたけど達成できなかったことが、増えている
    • つまり投入時間の増加は、成果の質向上と、達成できなかった目標へのアクションに使われている

2019年は、今年より目標を減らし、達成できる目標を増やすことが大切そうです。

またゲームに関しては、半年くらいの制作期間のものを複数リリースする予定だったのですが、1年に1本くらいのペースで制作し、パブリッシャーが捕まえられる程度のクオリティにしていく方が良さそうだなと思いました。

2019年やりたいこと

ゲーム制作

RPGアツマール向け ミニゲーム

これはもうイラストとサウンドを組み込むだけなので、やります。 そんなに工数かけず1月中にはリリースできるかと。

リリース後1週間ほどSNSで話題にされ、またゲーム自体は1ヶ月ほど 継続して総プレイ数が増えることが目標です。 (具体的な総プレイ数の目標はリリース時に考える...)

探索ホラーゲーム制作

ちゃんと完成版まで作ること、その上でコンシューマーゲームまで年内にリリースできることが目標です。 今 HTML5 で作ってるのですが、どこかで Unity で作り直さないとコンシューマーに移植できないので、Unity を学ぶことになると思います。

2Dアクションゲーム

イベントで体験版を1つ以上出せている状態を目指します。 これまでの作り方と違って、以下をやってみます。

  • 同ジャンルのゲームをきちんとプレイしてインプットする
  • プリプロ期間を設ける
  • 座組を作るところから始める。コミュ量たくさんして、初対面の人も巻き込んでいく

こちらも最終的にはコンシューマーゲームとしてリリースできることを目指していきたいところです。

Webサービス

同人音楽作家向けに、DL用プラットフォームの Webサービスを作るお話を頂きました。 企画1名 + エンジニア2名 + エンジニアリードの自分、という座組です。

エンジニアリードについてノウハウが積めているので、 それを適用しつつ、さらにブラッシュアップできればいいなと思っています。

開発体制や仕組みをきちんと整えることで、自分があまり手を動かさなくても プロジェクトが回り、プロダクトができていく状態にしつつ、 プロダクトが人々に受け入れられ、そしてメンバーが成長できたらいいなと思います。

2019年冬に最初のMVP(minimum viable product)リリースするのが目標です。

OSSプロダクト

HTML5 ゲームフレームワーク

これまで開発してきたゲームは、全て独自のゲームフレームワーク(FW)を利用しています。 実際にゲームに利用しつつ、独自FWを育ててきたのですが、 さすがに飽きてきたので、OSS としてリリースしようと思います。

気をつけないといけないことは、HTML5 FWは既に多数存在するので、 その中で新しいFWを出す意義を見出さないといけないことですね。

Github で star が 100 以上付くことが目標です。

リアルタイム通信サーバー

2018年に着手できなかったものを継続します。継続理由は以下の点で、 2018年当初と違って着手がより楽になっているためです。

  • golang にある程度理解ができたため、C++でなく golang で書ける
  • リアルタイム通信するゲームを作っており、ゲームクライアント実装者がサーバーに求める要件が理解できたため

Github で star が 1000 以上付くことが目標です。

会社を立てる

コンシューマー案件のゲームの売上次第では、インディーゲーム制作会社を 立ててもいいのかなと思います。(複業で)

現在一緒にゲームを作っているメンバーは、クリエイティブな仕事で生活したい意志があるものの、 スキルや経歴によって、なかなかそれが難しい状態にあります。彼らと会社を立てて、 彼らがゲームづくりでご飯が食べていけるようにしたい。

また、他にも継続的にメンバーを雇い育てることで、 社会に面白いゲームを継続的に提供できる組織づくりができればいいなと思います。

これはとりあえず現在のコンシューマー案件の結果次第で、また今年中の具体的な目標を立てる...。

次のゲーム制作案件 種まき

自分からゲーム制作していくだけでなく、ゲームを作りたい人から 依頼がきてほしいなと思うので、そのための種まきをしていきます。

以下の達成を目標としようと思います。

  • web サイトにて「制作依頼について」の項目追加
  • SNSや web 記事などで自分のノウハウや人へのインタビューの情報を発信(月1)

3D 勉強

2018年に引き続き。重要度と将来性からちゃんとやっていきたいところです。 とりあえず小規模なゲームを1つリリースすることを目標にします。

golang の Webフレームワーク gin のドキュメントを日本語に翻訳しました

この記事はDeNA Advent Calendar 2の 12月6日分の記事です。 枠が空いていたので、書かせていただきました。

翻訳しました

https://gin-gonic.com/ja/ から日本語ドキュメントが読めます。

gin とは

gin とは軽量かつシンプルなインターフェイスがウリの golang のWebアプリケーションフレームワークです。 また、golang の Webアプリケーションの中では比較的初期から開発されているので、 安定しており、プロダクション利用実績も多いフレームワークです。

私もお仕事で使わせていただいておりますが、特に癖もなく、 取り付きやすいフレームワークで助かっています。

きっかけ

gin の Web サイトは https://gin-gonic.github.io/gin/ ですが、 こちらはあくまで gin の紹介程度の内容となっており、各種APIの使い方などは、 README.md に掲載されている状況でした。

https://github.com/gin-gonic/gin/issues/1522 にて課題提起がされ、新しい Web サイト https://gin-gonic.com/ が作られました。(ドメインも新しくなっています)

まだ移行中のため、リンクなどは旧サイトのままですが、今後はこちらの Webサイトに各種ドキュメントは移行していくようです。

そのような中で、README.md の中国語翻訳のプルリクエスト が出され、マージされました。

中国語がマージされるなら、ということで、自分も README.md を日本語翻訳したところ、 日本語訳もマージされた次第です。

golang の採用事例は少ない

ではなぜ日本語翻訳したのかの話です。golang は様々な会社で採用される事例を聞くようになりました。 一方で、言語としてまだ新しい印象から、Web 業界全体として見ると golang を採用する事例が少ないように思います。

日本でWebアプリケーション開発する上で、 golang 及びそのフレームワークを採択する支障の一つとして、 ほとんどの golang の Web フレームワークには、日本語ドキュメントが存在しないことがあると思っています。

日本語ドキュメントのない技術の採択は難易度が高い

技術選択する上で、日本語ドキュメントが少ないことは、その技術を採択する上でのデメリットの一つだと思っています。 ソフトウェアエンジニアとして英語力の必要性は叫ばれておりますが、 一方で実際に技術選択をする立場になると、プロジェクトのメンバーが必ずしも英語の読解ができるメンバーばかりとは限りません。ジュニアなメンバーを考慮した言語選定、フレームワーク選定が求められることがあります。

gin の日本語ドキュメントが Web アプリケーション開発する際の golang や gin の 技術選択の助けになると嬉しいです。

終わりに

gin は良い Web フレームワークだと思います。これから golang を触ってみる人や、 あるいは、お仕事のプロジェクトで利用するフレームワークを選定する人は、 ぜひ gin を触ってみてください。

WebGL を利用して描画するまでの流れ

概要

WebGLを利用して描画する場合、描画までに実行する API のお約束が多い。

これは描画に必要なパラメータが膨大なため、 各API関数を呼び出して、グローバル変数である WebGL コンテクストの状態を変更していくことで、 描画に必要なパラメータを設定していく設計思想になっているためと思われる。

また WebGL の元となった OpenGLGPUハードウェアの制約の中で パフォーマンス向上のために API を追加し続けてきたため、 同じ描画を行う上でも、様々な方法がある(現在では推奨されないAPIもたくさん存在する)

流れ

  • GLContextの作成
var c = document.getElementById('canvas');
var gl = c.getContext('webgl');
  • シェーダーの生成

    • 頂点シェーダ
      • シェーダーの生成
        var shader = gl.createShader(gl.VERTEX_SHADER);

      • シェーダーにソースコードを割り当てる
        gl.shaderSource(shader, "shader source code");

      • シェーダーのソースコードコンパイル
        gl.compileShader(shader);

      • 正しくコンパイルできたことをチェック if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){ alert(gl.getShaderInfoLog(shader)); }

    • フラグメントシェーダ
      • シェーダーの生成
        var shader = gl.createShader(gl.FRAGMENT_SHADER);
      • 以降は頂点シェーダーと同様
  • プログラムオブジェクトの生成
    プログラムオブジェクトは、各シェーダーをまとめたもの

    • プログラムオブジェクトの生成
      var program = gl.createProgram();

    • プログラムオブジェクトにコンパイルしたシェーダを割り当てる
      gl.attachShader(program, vs); gl.attachShader(program, fs);

    • シェーダをリンク
      gl.linkProgram(program);

    • シェーダのリンクが正しく行なわれたかチェック
      if(!gl.getProgramParameter(program, gl.LINK_STATUS)){ alert(gl.getProgramInfoLog(program)); }

    • プログラムオブジェクトを有効にする
      gl.useProgram(program);
  • 頂点バッファを作る
    VBOやIBOが毎フレームごとに変更される場合は、描画の際に頂点バッファを作る必要がある

    • Vertex Buffer Object(VBO)

      • バッファオブジェクトの生成
        var vbo = gl.createBuffer();
      • バッファをバインドする バッファに値を設定するときは、WebGLContext に bind → set → unbind とする必要がある
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);

      • バッファにデータをセット
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);

      • バッファのバインドを無効化
        gl.bindBuffer(gl.ARRAY_BUFFER, null);

    • Index Buffer Object(IBO)

      • バッファオブジェクトの生成
        var ibo = gl.createBuffer();
      • バッファをバインドする
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
      • バッファにデータをセット
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(data), gl.STATIC_DRAW);
      • バッファのバインドを無効化
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  • VBO と IBOを登録
    シェーダー内の各変数(attribute変数、uniform変数)
    attribute変数...頂点ごとに異なるデータ
    uniform変数...頂点ごとに同じデータ

    • gl.getAttribLocation() gl.enableVertexAttribArray() gl.vertexAttribPointer() を利用してVBOを登録
    • gl.getUniformLocation() gl.uniformMatrix4fv() を利用して IBOを登録
  • 描画
    これまでの処理はプログラム開始時に1度だけ行えば良い
    描画は毎フレーム行う

    • canvasを初期化
      gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    • インデックスを用いた描画命令
      gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);

    • コンテキストの再描画
      gl.flush();

東京に来て2週間経った

部署移動のため大阪から引っ越して、東京に住んでおります。 職場の環境や人間関係、仕事内容、求められる知識が一新されて、 アワアワしております。社内転職に近い。

何をしているのか

ゲームの開発基盤作りをやってる部署に配属になりました。 部署としては、クライアントサイドのゲームエンジンや サーバーサイドや、開発する上でエンジニアやプランナーが 使うツール作りなどをしている部署です。

Ruby on Rails + Mithril で出来たWebアプリケーションを開発しているチームにアサインされました。

やったこと

主にフロントエンドの改修。 機能要件上の必要なタスクを1つ、 課題となっていたがなかなか着手できなかったタスクを複数やったりしている。 (実DOMを操作するライブラリのユニットテスト環境の整備など)

できてること

フロントエンドのキャッチアップ
もともと Mithril 触っていたというのもある

アウトプット
配属されてしばらく勉強ばかりということにはなっておらず、 何かしらアウトプットできてるのは良い。

引き続き、毎月、毎週、毎日、でも目標を立てて、それに対して成果を出していきたい。

アンラーニング
前の部署固有のドメイン知識に引っ張られることなく 現在の部署の仕事やあるいは知識に触れられている。

年末の冬休みで結構な時間を空けられたのが良かったのかもしれない。

できてないこと

社内の人とのコミュニケーション
引き続き自分が苦手だなぁと思っていること。 本来であれば、同僚や社内のキーパーソンに自らすすんで連絡を取って 交流するようしなくてはならないのだが..。

Rails のキャッチアップ
Rails tutorial やって、Rails アプリ多少作って業務にのぞんでたが全然ダメだった。

反省点は以下

全体的に Rails の学習時間が足りなかったからだと思うのだが、 Rails アプリ作るのも、環境構築に結構時間かかってたのが悪かった気がする。

今後は、新しい言語なりFWを学ぶ際は、環境構築に 大きく時間を取られることを念頭に置いておかないといけない。

すべきこと

コミュニケーション
無理をしてもお互いのためによくないので、できる範囲で。 人に対して真摯であるべきことは忘れないようしよう。

あと質問は積極的にしていこう。何事にも興味を持って。

コンテクストの学習
自分の部署は今こういうことをやっていて、それはこういう経緯があって、 誰のために今自分はシステムを作っていて etc... という情報は引き続き集めていく。

Rails の学習
この2週間の間も Rails ちゃんと調べて、以下の学びを得ました。

自分のように、別のスクリプト言語とFWの知識があって、 自分の腑に落ちるところまでAPIの挙動を把握していないとプログラできないタイプの場合、 まずは Rails のコードを読むために、Ruby メタプログラミングを学ぶのが良いですよという感じだった。 フレームワークを学習する際はソースコードレベルで理解しろ

終わりに

一緒のチームメンバーからはたくさんサポートをもらっております。 ありがとうございます。

肩肘を張っても空回りする時期ではありますが、実直にまずは 成果を積み上げて、信頼を得ていこうと思います。

2017年振り返り

過去ログ
2016年振り返り - まるまるこふこふ

目次

リードエンジニア

2017年4月~12月末まで、エンジニア約10名規模のチームにて、 リードエンジニアという役割を頂いてました。

リードエンジニアと言っても、会社やチームによってその肩書に期待される役割はそれぞれ違います。弊社での役割は概ね以下の通りです。

  • 主に技術的な面からメンバーの開発をサポート
  • チーム全体目線でのシステムの QCD 担保

メンバーの出したプルリクエストをコードレビューしたり、 あるいは、メンバーのアサイン調整や多職種との調整をしたりしていました。 (その代わり、コードを書く量はだいぶ減った)

各案件に対してのメンバーのアサインとフォローはしっかりと 取り組んだつもりで、本人の will や can を元に、 チームがうまく回るよう考えたつもりです。

おかげで、特にチームのエース級のメンバーたちが、 その高いパフォーマンスで存分にチームに貢献できる場を作れたと思っています。 (一人は皆から認められて、今はリードエンジニアとして活躍しています)

Project Indie

2017年2月くらいから、所属する会社の社内有志メンバーで、インディーゲームを作ってリリースできないかみたいなプロジェクトを進めてました。

プロジェクトの目的は以下です。 - プロジェクトメンバーの成長 - ゲームの企画/制作のナレッジの蓄積 - インディーマーケットの開拓

ゲーム制作の能力というのは、実際にゲームを作って、何度も市場からのフィードバックを得ることで、気づきや学びを通して成長するという、自分の原体験が元です。

デジゲー博や Bit Summit に出展することが目標でしたが、 結局 1作も 2017年にはリリースできませんでした…。

イベントへの出展や、メンバーが制作に時間を当てるための社内調整より、そもそもゲームを制作することや、あるいは公の場に出すことについての、メンバーの感じている壁の高さをきちんと払拭できれば良かったなと反省しています。

Project Indie は制作の場のプラットフォームで、その中で制作チームが3チームほどある形でして、そういう観点では、プロジェクトの発起段階で、どういう人たちに参加してもらいたいかの想定を、そして立ち上がった後は、メンバーのやりたいことやスキルなどきちんと把握しながら、それに合わせたサポートをすべきだったと思います。

個人制作ゲーム

個人制作の方のゲーム制作では、今年は完成版1作体験版1作出しました。

2Dアクションパズル制作

2作目です。2017年8月に完成版。 今回もイラスト、ドット絵、音楽、シナリオなど多くの人の手を借りて、完成できました。

ゲームの全体像をしっかり考えて、その上で細部まできちんと考えられるよう、頑張っていきたいです。

探索ホラーゲーム制作

3作目です。2018年12月に完成版予定。 2作目までは、自分が中心となって、他の方々とコミュニケーションしながら制作してましたが、今回は5名で一丸となって制作してます。具体的に言うと、週1頻度でSkype チャットでMTGしてます。

たくさん反響頂いて、良いお話も頂けてるので、来年も引き続き頑張ります。

技術同人誌

技術書典というイベントで、技術同人誌を2冊頒布しました。

Emscriptoon
Webエンジニアのためのゲームプログラミング入門

※どちらも現在は Booth にてDL形式で頒布しています。

登壇

emscripten & WebAssembly night !! #5
FRONTEND CONFERENCE 2017
YAPC::Kansai 2017

ブログ

【翻訳】goroutine の仕組み

今年はてブがついたのは上記くらい。

OSSコントリビュート

今年は特になし

自分がどう変わったか

登壇とブログの量がめっきり減りました。技術同人誌を書いていたときも思ったのですが、どうやら自分は日本語書くのがヘタだと感じるようになりました。全てのことをプログラミング言語で記述したい…。

0->1 でプロダクトを作ることが好きで、その上で技術選定していくことが得意なのだとわかりました。もしかしたらエンジニア皆そうなのかもしれませんが…。

今年は(主に個人制作で)サービスリードしたり、お会社の意思決定の仕組みにちょっと関われた一方、技術がおざなりになった年でもありました。

アウトプットの質と量の向上、そのための姿勢が変わったように思います。

2018年やりたいこと

ゲーム制作

昨年1.5本だったが、もっとたくさん出したい。 完成版のリリース2つ。進行中のゲーム2つくらい進めたいな。 (数を出せばいいってものでもないけど)

作品を手に取る人にどう思って欲しいか真剣に考え、そのために作品を設計していきたい。

Web サービス

1つ出したい。アイデアだけ今ある。ちゃんとユーザーファーストに考えて、きちんと長く使われるサービスにしたい。

OSSプロダクト

1つ出したい。アイデアだけ今ある。 どういうところが新しいのか、どういう風に利用者を広げていくのか、既存のプロダクトと何が違うのかをきちんと考えてやっていきたい。

もう一つ何か新しいアウトプットしたい

何も思いつかないけど、アウトプット量として上記は少なすぎる気がする(量が多ければいいってものじゃないけど)ので 何か新しい取り組みでのアウトプットしたい。

お会社でゲームの企画書出してみようかなぁ。

3D の勉強

今、2Dしかやれてないけど、3Dも作れるようになりたい。 コンシューマーの劣化ゲーみたいにならないようにしたいなぁ。

思想/哲学/歴史の本を読む

現代は人類の歴史の中でどういう時代なのだろう。この時代を自分はどう捉えればいいのだろう、この時代に私がしなくてはならないことは?みたいなことを最近よく考える。

これらの本を読んで、何かしら自分なりに答えが出せればなと。

チーム制作 上手になる

最近、人にモノをお願いさせていただいて、一緒に制作する機会が本当に増えた。自分にできないことを人にお願いする、人ができないことを自分がやる。その結果、一人では作れないものを作ることができる。分業だ。

一緒に制作する以上、時間を奪うし、作るものに対しての向こうの期待もある。 裏切らないように、責任を持ってやっていきたい。

人を動かす/説得する
「チームワークをするときは、全員が自然に心を動かされるように話しなさい」という言葉があるけれど、その通りだと思う。ともすれば論理建てて喋ると、ロジックは納得できるが、心が動かされない言葉になりがちなので、自分も気をつけていきたい。

これを作ることで、こんな目的が達成できるんだ、という言葉は、共感してくれた人を動かす力があるので、大切にしたい。

相手を熟知することは当然として、自らのテーマ、コンセプト、問題提起が何で、ゴールイメージが何で、依頼の仕方など、ちゃんとパートナーとして認めてもらえるよう振る舞っていきたい。

あと、人の良いと思ったところはちゃんと口に出そう。

彼らが力を発揮できる環境を作る
制作の仕組みや方法を考える/実行するのはもちろんのこと、最近は、文化の違いによる支障をよく感じる。思ったことをきちんと述べることが誠実な態度に見える文化で生きてきた人もいれば、相手の気持ちを慮って時として言わないことが正の文化で生きてきた人もいる。両者に摩擦があって、制作がうまく進まないのはもったいない。文化の違いを理解して、みなが心地よく良いパフォーマンスを出せる環境を目指したい。

姿勢について

  • 適当にすまさない/ごまかさない/全力で徹底して取り組む
  • 周囲に対する感謝の心
  • 身近な人に対して真摯かつ誠実である
  • 傾聴と自己開示(耳を傾ける事/説明すること)
  • 共感する
  • コミュニケーションの場があれば、その場をお互いにとって良い場にするかを意識すること

まだ未熟ではございますが、上記のことを意識して頑張りたいと思います。

今年もまたよろしくおねがいします。

【翻訳】goroutine の仕組み

訳者による概要

Krishna Sundarram 氏の記事「How Goroutines Work」の翻訳です。

「goroutine とは軽量スレッドである」という説明に対して抱くであろう 「どのようにして並行処理を実現しているのか」「既存のスレッド処理と何が違うのか」「なぜ軽量なのか」という疑問を解消する文章です。

とても良い文章なのですが、現在リンク切れになっており、 とてももったいないことだと思ったので、日本語に翻訳しました。

原文: How Goroutines Work (2017/12/02 現在、リンク切れ)

golang の紹介

もしあなたが golang 初心者で、並行処理(Concurrency)と並列処理(Parallelism)の違いがわからなければ、Rob Pike 氏のトーク (リンク先は英語)を参照してください。約 30 分のトークですが、30分視聴するだけの価値はあります。

違いを要約すると、「人が並行処理と聞いたときに想像するのは並列処理のことであり、それらは関連はしているがまったく別物である。平行処理とは、プロセス同士が独立して実行されることであり、並列処理はたくさんの計算を同時に実行すること(場合によっては互いに影響しあいながら)です」 並行処理とは一度にたくさんのことを扱うことであり、並列処理とは一度にたくさんのことを実行することです。*1

golang を使って、我々は並行処理プログラムを書くことができます。golang は、goroutine 及びそれら goroutine 同士が通信する仕組みを提供します。本文章では、前者の goroutine に焦点を当てます。

goroutine とスレッドの違い

Java がスレッドを使うように、golang では goroutine を使います。両者の違いは何でしょうか? この違いを語る上で 3つの要素があります。「メモリ消費量」「生成と破棄に要する時間」「スイッチングに要する時間」です。

メモリ消費量

goroutine は、メモリを大量に必要としません。スタック領域では 2kB しか消費せず、必要に応じてヒープ領域を割り当てたり開放したりします。*2*3一方でスレッドはスレッド間のメモリが干渉し合わないように「スタックガードページ」と呼ばれる 1Mb(goroutineの500倍) の領域の確保から始めます。*4

それゆえに、サーバーへリクエストがくるたびに、goroutine を生成するのは何も問題がないですが、スレッドでそれをやると、深刻な OutOfMemoryError が発生します。これは Java だけの制限ではなく、並行処理で OSのスレッド機構を使う全ての言語において、この問題に直面します。

生成と破棄に要する時間

スレッドは生成と破棄のたびに OS に要求を投げて、それが完了して返ってくるのを待つため時間がかかります。この問題を回避するには、一度生成したスレッドをスレッドプールに維持しておく必要があります。一方で goroutine では、生成と破棄に関する操作を非常に低コストで行うことができます。よって、golang では、goroutine を手動で管理する方法はサポートされていません。

スイッチングに要する時間

スレッドがブロックされると、別のスレッドがスケジューリングされます。 プリエンプティブ方式*5でスレッドがスケジューリングされ、スレッドの実行がスイッチされる際にスケジューラーは全てのレジスタ、つまり 16種類の汎用レジスタ、PC(プログラムカウンタ)、SP(スタックポインタ)、16種類の XMM レジスタ、 FP co-processor の状態、16種類の AVX レジスタ、そしてモデル固有のレジスタ etc... を別の場所に保存したり、保存したそれらをレジスタに戻す処理が必要になります。これはスレッド間で迅速にスイッチングしたい場合に、無視できません。

goroutine は協調してスケジューリングされ、スイッチングが発生したときも、たった 3つのレジスタ(PC、SP、DX)しか保存したり、レジスタに戻したりしません。これは非常に低いコストです。

以前に説明したように、goroutine の数は一般的にかなり多くの数になりますが、スイッチングにかかる時間に違いはありません。これには2つの理由があります。それは、実行可能な goroutine のみ考慮され、ブロックされた goroutine は考慮されないことと、また最近のスケジューラーは O(1) なため、実行可能な goroutine の数が、スイッチングの時間に影響を与えないからです。*6

goroutine がどのように実行されるか

前述したように、goroutine は生成から破棄までランライムが管理します。 ランタイムには goroutine が多重化された少数のスレッドが割り当てられます。 いつでも、それぞれのスレッドは1つの goroutine を実行します。goroutine がブロックされると、それはスワップアウトされ、別の goroutine が代わりにスレッドによって実行されます。*7

goroutine は協調してスケジューリングされるので、ループしつづける 1つの goroutine が、同一スレッド内の他の goroutine の実行を妨げることがあります。 Go 1.2 では、関数を実行する際に、Go のスケジューラーが呼び出されることがあるため、この問題は多少緩和されました。よって、ループ内でインライン関数でない関数を呼び出しておけば、他の goroutine がスケジューリングされます。

goroutine のブロック

goroutine は低コストであり、goroutine が以下の場合でブロックされた際に、それらが多重化されているスレッドのブロックを引き起こしません。

  1. ネットワーク入力
  2. sleep 処理
  3. channel 操作
  4. sync パッケージによるプリミティブのブロック

たとえ数万個の goroutine が生成され、それらがブロックされたとしても、 ランタイムが代わりに別の goroutine をスケジューリングするため、システムのリソースは無駄にしません。

簡単にいうと、goroutine はスレッドの軽量な抽象化です。 Go プログラマはスレッドを扱わず、また同様に OS は goroutine の存在を認識していません。OSから見れば、Go のプログラムは、イベント駆動の Cプログラムのように振る舞います。(脚注 6 参照)

スレッドとプロセッサ

ランタイムが生成するスレッドの数を直接制御することはできませんが、一方でプログラムが利用するCPUプロセッサの数を決めることはできます。 これは runtime.GOMAXPROCS(n) を呼び出して、変数 GOMAXPROCS を設定することで可能です。コアの数を増やしても、設計によっては必ずしもプログラムのパフォーマンスが上がるとは限りません。プロファイリングツールを利用して、プログラムの理想的なコア数を見つけることができます。

終わりに

他の言語と同様に、複数の goroutine によって、共有リソースの同時アクセスを防止することは大切です。goroutine 間でのデータのやり取りは、channel を通して行うのが最善です。共有メモリを通してデータのやり取りをするのではなく、代わりに channel を使って、メモリを共有します。*8

最後に、C. A. R. Hoare 氏による「Communicating Sequential Processes」を確認することを強くおすすめします。彼は本当の天才でした。1978年に発行されたこの論文で、彼はプロセッサの単一コアの性能が最終的に横ばいになり、チップメーカーは代わりにコア数を増やすことを予見しました。彼のプロポーザルの偉業は、Go 言語のデザインに深い影響を与えました。

*1:Concurrency is not parallelism」by Rob Pike

*2:Effective Go: Goroutines

*3:goroutine のスタック上でのサイズは、Go 1.4 から、8kB -> 2kB に減りました。参考

*4:Five things that make Go fast」 by Dave Cheney

*5:訳注 OSがプロセッサの実行権限を管理し,タスクの実行を切り替える方式

*6:Dmitry Vyukov 氏が、 golang-nuts グループにて gorouine のスケジューリングについて述べています。参考

*7:Analysis of the Go runtime scheduler」 by Deshpande et al.

*8:Share Memory By Communicating

技術書典3 で Emscripten 本出します。

f:id:sairoutine:20171020185653p:plain:w300

10月22日(日)に秋葉原UDXで開催される技術書典3にて

『Emscriptoon』を頒布します。

techbookfest.org

内容は Emscripten という C/C++ コードを JavaScript に変換するコンパイラを初心者向けに紹介した本です。

頒布価格は 500円。 サークルスペースは「い08」です。お手洗いの近くよ。

blog.techbookfest.org

入場に関しては整理券を配布するようです。 スマホで確認できるサイトがあるのでぜひ活用してみてくださいー。

blog.techbookfest.org

戦利品を片手に休憩できるスペースもあるみたいです。 数量限定でコーヒーとミネラルウォーターがあるって。

よろしくお願いします!