p_chinのおっぱいブログ

UnityとPerlなど

UnityProject内でのコードレビューとComponent設計をする時に気をつけてる事

このエントリはUnity Advent Calendar 2015の6日目の記事になります。

前日のエントリは@hecomiさんUnity で実行時にコードやコマンドを補完つきで実行できる uREPL を作ってみたでした。

デバッグがカッコ良くなるのもイケてますし、用途としてはコードをランタイムで実行出来るのがとても便利ですね!

さて、僕の方は『UnityProject内でのコードレビューとComponent設計をする時に気をつけてる事』について書いてきます。

コードレビューやコードを書く時の実体験に基づくあるあるネタを書きましたので、少しでも共感があれば幸いです><

アジェンダ

  • 前置き
  • コードレビューの時に気をつけてる事
  • UnityProjectのコードレビュー時に困る事
  • 設計の時に気をつけてる事
  • さいごの感想
    • 次の方の紹介

前置き

  • この記事内でのComponentとはUnityEngine.MonoBehaviorを継承したcsharpのclassの事を指します
  • コードレビューはgithubを使用して行っています

コードレビューの時に気をつけてる事

以下につらつらと書いてみました。 少しだけピックアップして列挙した項目を説明していきます。

  • そもそものpull−requestの作り方など
  • 汎用性があるか無いかによってディレクトリとclass名に気を使って欲しい
  • メモリ管理
  • null代入しないといけないとか
  • マジックナンバー
  • Componentの役割が明確か?
  • 一つのComponentに機能がつまりすぎて無いか?
    • ComponentのSetup関数は包有してるComponentの数だけ行数が多くなるので関数やComponentに分割したい
  • アニメーション処理などの座標計算処理に意味を持たせられてるか?
    • 関数名orコメントで説明するべき
  • 車輪の再開発をしていないか
    • 『これと同じ機能は昔書いたよ』というやりとりがたまにある

汎用性があるかor無いか

  • 汎用性があれば汎用的なComponent名にしてディレクトリも分けて欲しい
  • 汎用的でなければSceneや機能に適した命名にして欲しい

理由

汎用性があれば汎用的なComponent名にしてほしい

汎用的であるComponentは再利用される事を想定して作っています。

車輪の再開発にならない為に、チーム内で汎用Componet専用のディレクトリを作成した方が良いです。

(同じ開発チーム内で同じ機能のComponentを作ってしまい、それをコードレビューで気づく時がたまにあったので。。。)

僕は汎用Componentを作成したら他メンバーへ周知する様にしています。

汎用的で無ければSceneなどに特化した命名にすべき

これをしないと、ComponentのAutherはゲームのTOP画面でしか使う想定が無かったとしても、他の画面で別の開発者に使われてしまう可能性があるので。

(もちろんディレクトリ配置も気を使うべき)

アニメーション処理などの座標計算処理に意味を持たせられてるか?

そもそもコードレビューでアニメーションをレビューするのか?という問題がありそうですが、個人的にはコードだけ見て分かり辛い処理は気持ち悪いので説明を求めたりしちゃいます><

以下の様なコードが特に関数にまとめられてなくコメントもなく書かれてると何してるのか分からり辛い。

public voi Setup()
{
    // Componentの設定処理が書かれる

    HOTween.To(transform, 0.3f, new TweenParms().Prop("localPosition", new Vector3(1.2f, 2.5f, 3.4f)).Delay(0.1f));
    yield return new WaitForSeconds(0.3f);
    HOTween.To(transform, 1.1f, new TweenParms().Prop("localPosition", new Vector3(10.2f, 22.5f, 33.4f)));
}
......途中に上記の様なTweenアニメーションの処理がつらつらと書かれてる

こういったコードを見ると、『コメントでアニメーションを説明して!』とか『アニメーションを説明する関数にこの処理書いて!』とか言います。

一つのComponentに機能がつまりすぎて無いか?

Componentの良いところは他の画面で再利用出来る様に作ると開発が楽になる事ですよね。

なので、Componentは基本的に最小単位で実装するに限ると思っています。

そもそも500行とか超えたclassがそこらにあると、僕は読む時に疲れちゃいます(ヽ´ω`)

(ライブラリやUtility系のclassなら許せる)

こういうのとか見ると辛いなぁと思ってしまいます。

(僕はこの2倍のfieldが定義されてるclassを見た事があるので、以下は許容範囲かもとは思いますが)

public class HogeSceneUI : MonoBehaviour
{
    [SerializeField]
    private Label _coinNumberLabel;

    [SerializeField]
    private Sprite _coinIconSprite;

    [SerializeField]
    private Label _enemyNameLabel;

    [SerializeField]
    private Sprite _enemyIconSprite;

    [SerializeField]
    private Label _playerNameLabel;

    [SerializeField]
    private Sprite _playerIconSprite;

    [SerializeField]
    private Button _okButton;

    [SerializeField]
    private Label _okButtonLabel;

    [SerializeField]
    private CheckBox _checkBox;

    [SerializeField]
    private Label _checkBoxCaptionLabel;
}

こんな感じにIconのComponent作っちゃおうとか

public class CoinIcon : MonoBehaviour
{
    [SerializeField]
    private Label _coinNumberLabel;

    [SerializeField]
    private Sprite _coinIconSprite;
}

public class EnemyIcon : MonoBehaviour
{
    [SerializeField]
    private Label _enemyNameLabel;

    [SerializeField]
    private Sprite _enemyIconSprite;
}

public class PlayerIcon : MonoBehaviour
{
    [SerializeField]
    private Label _playerNameLabel;

    [SerializeField]
    private Sprite _playerIconSprite;
}

public class HogeSceneUI : MonoBehaviour
{
    [SerializeField]
    private CoinIcon _coinIcon;

    [SerializeField]
    private EnemyIcon _enemyIcon;

    [SerializeField]
    private PlayerIcon _playerIcon;

    [SerializeField]
    private Button _okButton;

    [SerializeField]
    private Label _okButtonLabel;

    [SerializeField]
    private CheckBox _checkBox;

    [SerializeField]
    private Label _checkBoxCaptionLabel;
}

そもそもUIにはヘッダーとフッターがあるからそれぞれのComponetを作ろう!とか

public class HogeSceneHeaderUI : MonoBehaviour
{
    [SerializeField]
    private CoinIcon _coinIcon;

    [SerializeField]
    private EnemyIcon _enemyIcon;

    [SerializeField]
    private PlayerIcon _playerIcon;
}

public class HogeSceneFooterUI : MonoBehaviour
{
    [SerializeField]
    private Button _okButton;

    [SerializeField]
    private Label _okButtonLabel;

    [SerializeField]
    private CheckBox _checkBox;

    [SerializeField]
    private Label _checkBoxCaptionLabel;
}

public class HogeSceneUI : MonoBehaviour
{
    [SerializeField]
    private HogeSceneHeaderUI _header;

    [SerializeField]
    private HogeSceneFooterUI _footer;
}

UnityProjectのコードレビュー時に困る事

  • SceneのHierarchyが見えない
    • Hierarchyの構造とComponentの親子関係に矛盾があっても気付けない(個人的になBroadcastMessageの様な機能があるのでHierarchyの構造は整理整頓されてあるべきだと思ってる)
    • レビューに渡されたコード以外のComponentがGameObectに与えてる振る舞いをコードを見るだけでは検知できない
      • GUIDを目で見れば良いけどそれならUnityでScene開いちゃった方が確実に早い
  • 大きいpull−requestを作ってしまう人が多い気がする

Hierarchyの構造とComponentの親子関係に矛盾があっても気付けない

以下の様な構成になってるHierarchyを見るとモヤモヤする。 UIControllerの中にCoinやTitleLabelなどのUIのGameObjectを入れて管理すれば良いと思う。

HogeScene
 - UIController
  - 色々なUIを表現する為のGameObject達
 - Coin
 - TitleLabel

大きいpull−requestを作ってしまう人が多い気がする

ゲームの新規開発の場合だと、一つScene の画面を完全に作りきってからpull−requestのレビュー依頼が来る時が辛い。 ただでさえコードから画面の振る舞いなどを想定してレビューするのが難しいのに...ぐぬぬ!!

個人的にUnityでの作業では、以下の様な粒度で細かくpull−requestを作って作業できると良さそうだと思ってます。 (辛い時には僕も気づくとたくさんの作業を一つのbranchでやってしまいますが。。。)

  1. デザインを再現したSceneのみ(Hierarchyの設計も含む)
  2. Componentのinterfaceのみ設計(開発に慣れてない人はおすすめ)
  3. Componentの実装
  4. 画面の演出などをブラッシュアップ

以下は各工程の軽い説明です

デザインを再現したSceneのみ(Hierarchyの設計も含む)

個人的にはSceneのレビューは手間がかかるので、縛りの強いRailを敷きたい感じが最近はしております。 (レビューしなくても最低限の品質が保たれるように)

  • 開発チーム内で決めたSceneの構成になってるかをチェック
  • drawcallの無駄遣いをしてないか?なども見る
  • レビューの度に作業branchをcheckoutして見るのはシンドイのでチームに入りたての人のみ見たりしてる

Componentのinterfaceのみ設計(開発に慣れてない人はおすすめ)

主に実装完了してからのレビュワーによるチャブ台返しへの対策。 トータルの開発時間の節約にもなるし、レビュワーは段階を踏んで学びを得られそう。

  • 開発経験が浅いorチームの開発ルールに慣れてない人が対象
  • Componentが持つ変数・関数・他Component間のデータの流れなどを評価

設計の時に気をつけてる事

今まで書いた事で設計の時に考える事が大体網羅されてしまったので新しいネタを思い出してました...

僕がSceneの実装前に考えてる事は以下の事です。

  1. 他の画面と共通要素になりそうな箇所をデザイナーと相談しよう
  2. Hierarchyの構造を設計しよう。
  3. とりあえず空のGameObjectでもいいから置いておく
  4. Hierarchyの設計をしたらComponent設計を始めよう
  5. Hierarchyの構造が決まった後だと画面を構成する部品を頭の中で分解した後なので、役割分担を想像しやすく設計しやすい

特にゲームの開発初期にはとても時間をかけていた気がします。

汎用Componentや拡張性を考慮したコードをプロジェクトの初期に書いておくと、後でリリース前の辛い時にコードを書いても品質がある程度守られるからです。

さいごの感想

Component設計やコードレビューの話を書いてみましたが、正直持論的な部分があるのでもっと本を読まないとな...と思いました。

今読んでる途中のCodeComplete(上)には設計的なノウハウのエッセンスが多く書いてあるので勉強になります。

(薦められてから1年経ちますがまだ読了出来ておりません。。。)

また、他のUnityエンジニアの方が仕事でどのようにコードを書いているのか意外と知らないので気になりました。

次の方の紹介

さて、次の12/7のエントリはLINQおじさんこと @RyotaMurohoshi さんによる 『Androidネイティヴプラグインを作る際の注意点!』という題材で書いてくださいます。

今回LINQネタは出ないでしょうが、きっと面白い内容になると思うので楽しみです!

関数の宣言まわりで地雷踏んでUnityのmonoでInternalCompilerErrorが出てしまったのを解決した話

問題

以下の様なコードをUnityのmonoでコンパイルしたらInternalCompilerErrorを出してしまった。

コード

public class Bomb
{
    public void Explosion(float radius = 10f){}
    public void Explosion(Vector3 worldPos, float radius = 10f){}
}

public class BomberMan
{
    public void ExecuteExplosion()
    {
        var bomb = new Bomb();
        bomb.Explosion(radius: 100f);
    }
}

InternalCompilerErrorの一部

Internal compiler error. See the console log for more information. output 

-----
UnityEngine.dllとかで握りつぶされてた大量のwarningが書かれてた
-----

Unhandled Exception: Mono.CSharp.InternalErrorException: VerifyArgumentsCompat didn't find any problem with rejected candidate MethodBuilder [{エラーが出てる関数名}]
  at Mono.CSharp.MethodGroupExpr.OverloadResolve (Mono.CSharp.ResolveContext ec, Mono.CSharp.Arguments& Arguments, Boolean may_fail, Location loc) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Invocation.DoResolveOverload (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Invocation.DoResolve (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Expression.Resolve (Mono.CSharp.ResolveContext ec, ResolveFlags flags) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Expression.Resolve (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Argument.Resolve (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Arguments.Resolve (Mono.CSharp.ResolveContext ec, System.Boolean& dynamic) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Invocation.DoResolve (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Expression.Resolve (Mono.CSharp.ResolveContext ec, ResolveFlags flags) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Expression.Resolve (Mono.CSharp.ResolveContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.ExpressionStatement.ResolveStatement (Mono.CSharp.BlockContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.StatementExpression.Resolve (Mono.CSharp.BlockContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.Block.Resolve (Mono.CSharp.BlockContext ec) [0x00000] in <filename unknown>:0 
  at Mono.CSharp.ToplevelBlock.Resolve (Mono.CSharp.FlowBranching parent, Mono.CSharp.BlockContext rc, Mono.CSharp.ParametersCompiled ip, IMethodData md) [0x00000] in <filename unknown>:0 

原因

以下の条件が重なるとダメっぽい

  • 引数をOptionalにしてる
  • ex. float radius = 10f
  • オーバーロードした関数が元の関数と引数の順番が違う
  • 今回の場合はオーバーロードする時に『第一引数のworldPosをOptionalにしたくない』という理由で引数の順番を変えてしまっていた様子
    • (前の引数がOptinalだった場合には以降の引数もOptinoalにしないとコンパイルエラーになるので)
  • 呼び出し側が引数のパラメータ名付きで引数を送ってる
    • ex. bomb.Explosion(radius: 100f);

解決方法

以下のどれかの方法を取れば解決する

  • BomberMan.ExecuteExplosion()bomb.Explosion()の引数指定にパラメータ名を添えるのをやめる
  • Bomb.Explosionの引数であるradiusをOptionalにしない
public class Bomb
{
    // `Bomb.Explosion`の引数である`radius`をOptionalにしない
    public void Explosion(float radius){}
    public void Explosion(Vector3 worldPos, float radius){}
}

public class BomberMan
{
    public void ExecuteExplosion()
    {
        var bomb = new Bomb();

        // `BomberMan.ExecuteExplosion()`で`bomb.Explosion()`の引数指定にパラメータ名を添えるのをやめる
        bomb.Explosion(100);
    }
}

追加情報

@shogo82148 が調べてくれてた

shogo82148.github.io

monoのrepositoryでは、既に修正が入ってるっぽい https://github.com/mono/mono/commit/7ad366c25a7fc180a57dcf88f28064ec3db619b6

でも、Unityの中のmonoにはこの修正はまだ取り込まれていない様だった https://github.com/Unity-Technologies/mono/blob/unity-staging/mcs/mcs/ecore.cs#L3794

StackOverFlowだとここら辺の情報が今回の件に該当しそう http://stackoverflow.com/questions/4495108/mono-named-optional-parameters-compiler-bug

BitmapFontの更新をSceneからの参照を保ったまま更新する手順

ある程度画面を作成してきたところでBitmapFontの更新があって、SceneからのUIFontの参照を保ったまま更新したいと思ってて悩んで解決に至ったのでメモ。

※UIFontの公式の機能を使ってるだけです。

  1. BitmapFontGeneratorで更新したいフォントデータ(.fnt, .png)を生成
  2. Unityに.fnt.pngをimportする(また手動でmaterialから参照し直すので既にあるデータから上書きしても良い)
  3. {font_name}.prefabのInspectorでのUIFontのパラメータのImport Dataに先ほどimportした.fntをD&DしてBitmapFontに収録されてる文字と、画像に対する文字のoffsetなどのデータを更新する
  4. フォントデータを更新してBitmaoFontのAtlasの文字に対するoffsetが変更されたので、2の工程で上書きしたAtlasの.pngファイルがUIFontが参照してるmaterialから参照されてるかチェック

BitmapFont、Mac<->Win間のやり取りが面倒なのでたまにしかやらない作業だけど辛い。

Unityの4.2.2から変わってる俺得そうな変更をまとめた

なんかUnityの最新versionを使ってゲーム作りたかったり、そろそろiOS8のよさげなfeatureが出て運用中のタイトルのUnityVersionupもありそうだなと思ってたので

普段仕事で使ってるUnity4.2.2から最新までの変更を見てたので、まとめる。

ちなみに当方、EditorやAPIのfeature以外はあんま仕事で使って無いのでそれらの変更に関しては多少抜いてます。

対象

これから運用タイトルの4.2系のUnityをドカッとアップグレードする場合には多少の知見になるかもです。

4.2.2-4.5.4までのRelease Notesを読んでざっくり俺得な修正をまとめてみる

4.3

Editor

  • エディターの新 API に、エディター上の要素を強調表示する Highlighter を追加。エディター上でチュートリアルを提供する場合などに有用
  • 新規アセットまたは実際にコンテンツが変更されたアセットのみがインポートされるように(タイムスタンプだけ変更されたアセットは再インポートされない)
  • Shift + F キーまたは F キー2 回押しでシーンビューのカメラを選択中の GameObject にロックするよう変更
  • プロジェクトのロード完了前にアクティブなビルドターゲットを選択する新コマンドラインスイッチ "-buildTarget " を追加
  • エディターのプロファイリング時に OnGUI イベントがプロファイリングされるように変更

Script

Android

  • Adreno デバイスの glTexSubImage2D を無効化。ダイナミックフォントに関する一部問題を修正

4.3.1

特に無し

4.3.2

特に無し

4.3.3

Android

  • Snapdragon 搭載デバイス上でアプリケーションが突然終了してしまう問題を修正
  • ステータスバーの高さ分だけタッチ入力がオフセットされる場合があった問題を修正

iOS

  • WWW ダウンロードのキャンセル時にクラッシュしていた点を修正

4.3.4

iOS

  • WWWでサイズの大きいファイルをダウンロードする時に失敗していた問題を修正。

4.5

モジュールマネージャー

アップデート可能なプラットフォームサポートを含むモジュールマネージャを導入。iOSAndroidWindows Phone 8Blackberry Unity アドオンは、エディターの完全インストーラーをダウンロードしなくてもアップデートできる。本機能は「プリファレンス」メニューの隣にある「モジュール」メニューから使用可能

エディター機能

新しくなった階層ウィンドウのソート - 各要素のソートはトランスフォーム順になるように変更 新しいエディター API 「AssetDatabase.FindAssets」(string filter、string folders)を導入。ファイル名、タイプ、アセットラベルを基に、アセットデータベースを検索できる。詳細は資料にて確認のこと プロジェクトブラウザ内で現在選択中のアセットを取得する Selection.assetGUIDs を追加。また、プロジェクトブラウザ(2 列表示時)の最初の列で選択しているフォルダの値も返す。なお、これはメインの選択に含まれない

Unity Remote アップグレード

Unity Remote 4 は、iOS および Android 向けのプレイテスト用ソリューションです。Unity 4.5 では、iOS デバイスでテストを行う際にも Wi-Fi の遅延は発生しません。また、加速度センサー、ジャイロ、カメラ画像を含む、あらゆる iOS デバイス入力に対するサポートを追加しました。Unity Remote 4 は、Google Play またはApp Store から無料でご利用いただけます

Editor

Script

  • UNITY_PRO_LICENSE の定義を追加

Serialize

  • シリアライズ(インスタンシエイションやレベルローディングなど)MonoBehaviors のパフォーマンスを 2 倍~5 倍改善
  • 最高!

Substance

  • エディターのメモリ消費を低減
  • エディター内の Substance 処理 は、プレイモード以外では常時マルチスレッド化されるようになった
  • iOS/Android 上におけるランタイム PVRTC 圧縮が高速化および高品質化

WWW

  • 「WWW(string url, byte postData, Hashtable headers)」を廃止予定としたため、かわりに「public WWW(string url, byte[] postData, Dictionary headers)」を使用すること

Android

  • プリロードされたスレッドは、アプリケーションがポーズ状態であればバッテリーを消費しないようになった
  • バックグラウンド起動時のバッテリー消費量が減った?
  • 一部の Adreno GPU で動作する Android 4.4.2 でクラッシュが発生していた問題を修正

iOS

  • WWW リークを修正
  • XCode 5.1 で動作するよう XCode プラグインをアップデート(ビルドおよび実行は動作する見込み)
  • あれ、今までXcode5.1.1でビルドして問題無くゲームプレイ出来てたけど...

4.5.1

特になし

4.5.2

Substance

  • 初期のシーンロード後のメモリフットプリントを低減

4.5.3

Scripte

  • Resources.LoadAsync() を追加し、Resources フォルダからアセットを非同期でロードできるようにした(Pro のみ)

4.5.4

Android

  • IME で Back ボタンを押して閉じようとした時にアプリケーションがクラッシュしてしまう問題を修正しました。

4.6

  • UI周りのEditor機能が一新してるっぽい

以上

ザックリと変わってる所まとめ

  • UnityEditorでの作業が早く快適になってる
  • SceneのLoadやInstansiateの速度が早くなったっぽい
  • ビルドされたアプリケーションの実行時のパフォーマンスが良くなってる
  • 2Dゲームの制作に特化した作業方式が追加されてる
  • Android特有の不具合が色々解消されてる
  • モジュールマネージャの追加によってUnityEditorのversionupをしなくても、AndroidiOSなどの分離されたモジュールだけのfeatureをアップグレードする事が出来そう
    • Unityのversionupって運用中のタイトルだとAssetBundle(AB)の再生成が必須で今のゲームのメンテ入り確定なので少し助かる
      • サーバーに2種類のversionのABを置いてversion毎にLoadする仕組みさえ有ればメンテ要らないかもだけど...

フロントエンジニアだけどYAPC::Asia2014に行ってきたので特に楽しかった講演とその感想

今年は1年以上、業務でPerlを触ってないけどまだ自分でも楽しめそうなセッションがあったので、主に 業務効率化リリース管理 などの話題に絞って講演に参加してた。

印象に残った講演と、その感想を書いて行く

1日目

完成されたシステムなどない。完成された人間もいない。あるのは成長し続ける未完成なシステムと、それを支える未完成な人間だけだ - YAPC::Asia Tokyo 2014

@kenjiskywalker さんの講演。

少し遅れて講演会場に入ったのだが、スライドに映ってたのは宇宙の写真とステージを練り歩きながらボソボソとゆっくり喋っているケンジさんだった、シュールだ。

Webサービスの誕生と宇宙の誕生を照らし合わせている用でした。 おそらく前代未聞で開拓的な講演でした。

yapcasia2014 // Speaker Deck

コマンドラインツールについて語るときに僕の語ること - YAPC::Asia Tokyo 2014

@deeeet さんの講演。

serverのプログラムは書かないけど、業務効率化ツールはフロントエンジニアでもたまに書く機会があったので有益だった。 コマンドの引数やオプションの順番や、ドキュメントの重要性についても書いてあって、正しい事の再認識を出来た様な気がした。 スライドも見やすかったし、ベストスピーカー3位になってた講演だった。

コマンドラインツールについて語るときに僕の語ること #yapcasia // Speaker Deck

2日目

モバイルアプリとAPIのありかたを考える2014 - YAPC::Asia Tokyo 2014

@ar_tama さんの講演。

良くtwitterで見かけるし、生で見たときこの人かー!ってなった。

MBaaA(Mobile backend as a Service)という言葉は知ってたけど、その意味と言葉が自分の中で別のモノだったのでここで知れて良かった。 最近はカジュアルゲームでもユーザのTokenやシリアルコードキャンペーンなどもしたかったりする要望が多いので、こういうデータストアやちょっとしたapiも作れる様なserviceは便利っぽいと思った。

モバイルアプリとAPIのありかたを考える2014 // Speaker Deck

Mobile Application Development for Perl Mongers [ninjinkun x gfx] - YAPC::Asia Tokyo 2014

@gfxさんと@ninjinikunさんの講演

今回のYAPC唯一のモバイルアプリケーションのお話で、僕にはド真中ストライクな内容だったので興奮した リリース管理やテストなどの不満は大体同じ認識だったので共感できた。 また、あまりゲームなどのクライアントサイドの開発フローなどの知見があまり広まってない気がするので、そんな中での発表だったから個人的に嬉しかった。

Mobile App Development for Perl Mongers // Speaker Deck

まとめ

perlの話題にもう付いて行けないので不安だったけど、なんだかんだで楽しめた。 Web界隈の人のOpen & Shareの精神素晴らしいと思ってる。 なかなかゲーム作ってる人は業務に依存しすぎて技術情報を発表出来てないイメージを勝手に想像してるけど、 ゲーム開発者も外部に知見を共有して行かなきゃなぁと思った。

運営の方々やスポンサーのおかげで美味しいご飯や酒を浴びれたと思うので、ありがとうございました!