Unityのmetaファイルについての勉強会を行いました


こんにちは、エンジニアの堀尾です。

今回の開発者ブログは以前プロジェクト内で行ったUnityのmetaファイルについての勉強会のお話です。

勉強会を行った経緯

Unityを使用する上でmetaファイルは非常に重要です。しかし、エンジニア以外の人たちにとっては謎のファイルという認識になっておりたびたび問題が発生していました。

  • 問題の例
    • metaファイルのコミットを忘れたことでAssetの関係を保持できなくなる
    • GUIDが競合してしまい、エフェクトやモデルが正しく表示されなくなる

そこで、metaファイルとは何なのかどういった働きをしているのかを資料としてまとめ、勉強会を行いました。


プロジェクトのプランナーさんとデザイナーさん向けに発表を行ったのですが、内容が難しかったのか後半になるにつれ眠そうな人がちらほらと…。しかし、「今までただ謎のファイルとしか認識していなかったけど何となくわかった気がする」と言ってくれる人もいたので勉強会自体は開いてよかったなと感じています!

おわりに

勉強会を行っただけで全ての人がmetaファイルについて正しく理解できた訳では無いと思いますが、理解するまでの第一歩は踏み出せたのではないかなと思っております。


「関西ゲーム勉強会 2016夏」にスタッフとして参加してきました


6/25(土)「関西ゲーム勉強会 2106夏」が開催されました。
Aimingはこの勉強会のプラチナスポンサーとして協賛させて頂きました。

http://kgstudy.com/

この勉強会に運営スタッフとして参加しましたので、レポートを書かせて頂きたいと思います。

関西ゲーム勉強会とは?

有志が運営する、関西のゲーム開発者同士の交流の場を提供するコミュニティです。
年2回〜3回、勉強会を開催しています。

以前は、「関西ソーシャルゲーム勉強会」という名前でしたが、スマホだけで無く、広くゲーム開発者同士を結び付けたいという意図で、現在の勉強会名となりました。

今回の勉強会について

「関西ゲーム勉強会」は、今回で通算10回目の開催となりました。

前回までは、スポンサーを取らず、100名程度の規模で開催してきたのですが、10回という節目もあり、もっと大きな規模での開催に挑戦してみました。

参加者数を300名とし、登壇者数も大幅に増やしました。
運営メンバーの中には、スポンサーが本当に集まるのか不安な意見もありましたが、弊社を含む、多数の企業様にご賛同頂けました。

弊社はプラチナスポンサー登壇枠を頂きましたので、大阪スタジオ・エンジニアマネージャーの槙石が登壇しました。

開催してみて

グラフィック・チームビルディング・UI・データ分析・コンシューマ開発と多岐に渡る登壇内容となり、多くの来場者に喜んで頂けたのではないかと思います。

セッションは10時から始まり、途中で昼休憩を挟み、午後の部が開催されました。
午前中は来場者が少ないのではないかと予想していたのですが、最初のセッションから参加して頂く方がほとんどでした!
(最初に用意していた椅子が足りず、急遽、隣の部屋から運びこむことで対応しました。)

また、一部、入場制限を行ったセッションもありましたが、大きなトラブルも無く開催することができました。

懇親会!

恒例となっている懇親会は毎回大きく盛り上がり、開発者同士の交流の機会となっています。
今回は会場の都合でノンアルコールとなってしまいましたが、前回の倍以上の規模となり盛り上がりました!

懇親会内のLTでは、スマホ版ログレス開発チームの藤井も登壇しました。

Aimingのブースでは、弊社の雰囲気をお伝えしたり、エンジニアと気軽にお話頂くために、急遽その場のノリでAimingブースに「ゆるい相談所」を開設してみました。

kgs_booth

スマホゲームの開発に興味のある方々が訪れ、弊社での職種毎の業務内容や、インターンの内容等の質問があり、弊社のエンジニアがお答えしました。

今後

次回開催は、今年の冬頃になるかと思います。

今回はスポンサーを募集することで規模を拡大し、良い経験となりましたが、また多くの反省点も残しました。受け付けの対応で長い列が出来てしまっていたり、セッション枠をもっと時間的な余裕のあるものにしたりと、課題は多いです。

きちんと振り返りを行い、次回はさらにパワーアップした内容で開催したいと思います!


小林俊仁

dots. ゲーム部のローンチイベントで登壇してきました


小林です。
昨日は dots. ゲーム部のローンチイベントで登壇してきました。

dots. ゲーム部 2016-06-28 会場

ゲーム業界の、エンジニア、プロデューサー、ディレクター、デザイナー、経営者等々いろんな方々が来るということで、内容はある程度一般化できるものに限られましたが、資料は Speaker Deck に上げておきましたので眺めて頂ければと。 普段面談とかしてる人は聞き慣れた話なのかもしれませんが。
Aiming はこういった方向性についてリーダー陣がブレずにやれてる、本当に稀有な環境だと思います。

また、今回一緒に登壇した方々のプレゼンも、いろんな視点が手に入って楽しかったです。 皆いろんな立場で頑張ってて刺激を頂きました。

ちなみに、今回のイベントでモデレータを務めて頂いたのは、シシララの安藤さんでした。
実は僕の社会人人生は Community Engine という会社にほぼ住み着いてゲームとプログラミング漬けの日々を送ったところからはじまったのですが、安藤さんはその上の階で働いていたこともあって友達付き合いしてまして、お互いスクエニと Community Engine をやめた後も巡り巡ってこういう形でコラボできるのは感慨深かったりもします。 思えば 15年くらいの付き合いになるのですかね。

dots. ゲーム部 2016-06-28 安藤+小林1

dots. ゲーム部は、今後コミュニティとして拡大していきたいそうです。 懇親会とかで社外の人と交流できますので、気になる方は次回以降も参加されると良いのではと。

dots. ゲーム部 2016-06-28 登壇者

というわけで、皆様本当にありがとうございましたー。


ヴァリアントレギオンで利用しているSlackBOTについて


こんにちは。エンジニアの山内です。

Aimingでは社内のチャットツールとして Slack を使用しており、ヴァリアントレギオン (以下ヴァリレギ) のチャンネルでも、いくつかのBOTが動作しています。

KPT入力を催促するBOT

ヴァリレギのチームでは、Trello に Keep, Problem, Try を思いついた時に入力しておき、スプリントのタイミングで入力された内容を見返してKPTを進行しています。
ついつい忘れがちなため、毎日特定の時間になると Trello へ KPT の入力を要求するBOTがいます。KPTをやかる(※)BOT と呼ばれています。

※やかる:方言。(強引な理由の)文句を言う。訳すなら「KPT入力(されてない事に)文句を言うBOT」。

レビューを催促するBOT

ヴァリレギのチームでは、レビュータイムを設けてレビューが溜まってしまう状況を低減しています。レビュータイムをBOTが通知します。

Pivotal確認を催促するBOT

ヴァリレギのチームでは、PivotalTrackerでストーリーの管理をしています。実装ができて Accept を行うのはプランナーチームになるため、完了しているストーリーが無いか確認を催促するBOTがいます。

bugbot

最近はTODOも通知するようになりました。

担当決めBOT

急ぎで見てほしいレビュー、調査依頼など、誰かに依頼したいけど誰に投げるか決めにくい。かといって、@誰か ではなかなか拾われない。ということで、担当をランダムに抽選するBOTがいます。

これは あなたのチームの「いい人」は機能していますか? というスライドで紹介されていた手法です。

エリス 担当 <人数>

と入力すると担当者をピックアップしてくれます(エリスはヴァリレギ内でプレイヤーに色々教えてくれるキャラクターです)

eris

なぜか作成者が抽選されにくい現象が発生しましたが、コードに不正はありませんでした。
コマンドが日本語で打ちにくいと言う意見があり、エリスの多言語化が要求されています。

これらのBOTのおかげでチーム内のコミュニケーションが円滑になっています。


chiepomme

静的コード生成を用いたシリアライゼーション高速化


こんにちは、とある新規開発プロジェクトで主に C# でクライアントとリアルタイムサーバーを書いている 水上智絵(@chiepomme)です。今回は私のプロジェクトで行った、C#におけるシリアライゼーションの高速化についてお話ししたいと思います。

はじめに

いま私が関わっているプロジェクトで以前、通信が多くなると動作がカクカクしてしまう問題が出ていました。Unity のプロファイラで調査したところ、ほとんどがシリアライズ・デシリアライズのコストだったことから、シリアライズの処理を高速化する必要が生まれました。今回はその方法についてご紹介します。

そもそもシリアライズってなんだ!

シリアライズというのは、プログラムの中のオブジェクトを、ファイルに書き込んだり通信に乗せたり出来るようなバイト列(文字列)に変換することです。逆にバイト列からプログラム中のオブジェクトに変換することをデシリアライズといいます(由来は知らないのですが、シリーズとかシリアルと同じ言葉なので、一続きのもの、つまりバイト列一本にするからシリアライズというイメージで私は考えてます)。

たとえば、以下のようなクラスがあったとします。

class SerializableObject
{
    public int A = 10;
    public int B = 20;
}

これをファイルに保存したい、通信に乗せたいとなった場合には、「A:10, B:20」のようなテキストでの表現や、値である「10 20」をそれぞれバイト列に変換してつなげるというのが素直な方法だと思います。こういった処理をシリアライゼーション、動詞だとシリアライズする、と言います。

リフレクションを用いた汎用的なシリアライザーとパフォーマンス

さて、こうしたシリアライゼーションは小さな物であれば個別のクラス毎に定義することが可能ですが、規模が大きくなってくるとそうするのは現実的では無くなってきてしまいます。そこで色んなクラスに汎用的に使えるシリアライザーが必要となります。

汎用的なシリアライザーとしては代表的なのは C# を使い始めた頃きっとだれでもお世話になるであろう XmlSerializer です。コードは GitHub で見られます。
https://github.com/dotnet/corefx/tree/master/src/System.Xml.XmlSerializer/src/System/Xml

このコードを見てもらうと分かるのですが、通常こういったシリアライザーを作る場合にはリフレクションが必要となります。しかしリフレクションは動作が遅く、保存データの読み書きであれば問題になることは少ないと思いますが、リアルタイム通信に用いるような箇所に使用すると速度的にボトルネックになりやすいという問題点があります。

最新の C# を使えてかつ動的コード生成に対応している環境であれば、様々な方法でリフレクションを用いずにも、動的にオブジェクトにアクセスすることが可能です。具体的な方法は以下の岩永さんのブログをご覧ください。

[雑記] 動的コード生成のパフォーマンス – C# によるプログラミング入門 | ++C++; // 未確認飛行 C

しかし、Unity の C# は若干古く、また iOS では動的コード生成ができないという制約があります。よって、私たちのプロジェクトでもキャッシュを用いて改善を試みましたが、それだけでは満足のいく改善が見られませんでした。その後も細かなチューニングをしてみたもののそもそものリフレクションのパフォーマンスの問題があるため、天井が見えてしまっていました。

リフレクションから静的コード生成へ

大きな改善のためには根本的な発想の転換が必要だと思い、動的な仕組みでは無くシリアライズの方法自体を静的に生成してしまうという方法を考えました。ただ C# には静的なコード生成をサポートするような仕組みはないので、本当にコードそのものを生成してあげる必要があります(幸い Aiming には JSON Schema を用いた Generator のような、通信定義 DSL を書くことで通信ファイルを生成する仕組みがあるため、それに載せて使用しています)。

では、実際に C# のコードで比較してみましょう。

シリアライズしたいクラス

話を単純にするために以下のような、入れ子を伴わず、フィールドの型も int もしくは string のみのクラスを対象とします。また、シリアライズ先のフォーマットはテキストで「フィールド名<タブ>値<改行>…」とします。

public class SimpleSerializableObject
{
    public int Int1;
    public int Int2;
    public int Int3;

    public string String1;
    public string String2;
    public string String3;
}

(from https://github.com/chiepomme/SampleSerializer/blob/master/Serialization/SimpleSerializableObject.cs)

リフレクションを使用したコード

using System;
using System.Reflection;
using System.Text;

namespace Serialization
{
    public class StringSerializerWithReflection
    {
        public string Serialize<T>(T serializableObject) where T : new()
        {
            var stringBuilder = new StringBuilder();

            // シリアライズ対象クラスの全てのフィールドを取得
            var fields = typeof(T).GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
            foreach (var field in fields)
            {
                // キー + タブ + 値 の形で文字列にする
                stringBuilder.AppendLine(field.Name + "\t" + field.GetValue(serializableObject));
            }
            return stringBuilder.ToString().Replace("\r\n", "\n");
        }

        public T Deserialize<T>(string serializedString) where T : new()
        {
            var resultObj = new T();
            // デシリアライズ対象クラスの全てのフィールドを取得
            var fields = typeof(T).GetFields(BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance);

            foreach (var line in serializedString.Split('\n'))
            {
                // キー + タブ + 値 の形で格納されているのを取り出す
                if (string.IsNullOrEmpty(line)) continue;
                var nameAndValue = line.Split('\t');
                var name = nameAndValue[0];
                var rawValue = nameAndValue[1];
                var field = Array.Find(fields, (e) => e.Name == name);

                SetValueToField(resultObj, field, rawValue);
            }

            return resultObj;
        }

        void SetValueToField<T>(T resultObj, FieldInfo field, string rawValue)
        {
            // テキストをフィールドの型でパースして実際の値にする
            if (field.FieldType == typeof(int))
            {
                field.SetValue(resultObj, int.Parse(rawValue));
            }
            else if (field.FieldType == typeof(string))
            {
                field.SetValue(resultObj, rawValue);
            }
        }
    }
}

(from https://github.com/chiepomme/SampleSerializer/blob/master/Serialization/StringSerializerWithReflection.cs)

シリアライズ時には、リフレクションで全てのフィールドを走査して、それぞれの名前をキーとして StringBuilder に追加していき、最終的な文字列を構築します。デシリアライズ時にはその逆のことを行うだけの単純な物です。

静的コード生成による方法

リフレクションを使わず静的コード生成を用いる時には、ビルドより前にシリアライズ対象のクラスに対応したシリアライズ・デシリアライズメソッドを生成する必要があります。今回の場合にリフレクションを使わずリフレクションと同じ事をするためのコードは以下のようになるでしょう。

// このファイルは StaticStringSerializerGenerator によって生成されました
using System.Text;

namespace Serialization
{
    public partial class SimpleSerializableObject
    {
        public string Serialize()
        {
            // キー + タブ + 値 の形で文字列にする
            var sb = new StringBuilder();
            sb.AppendLine("Int1\t" + Int1);
            sb.AppendLine("Int2\t" + Int2);
            sb.AppendLine("Int3\t" + Int3);
            sb.AppendLine("String1\t" + String1);
            sb.AppendLine("String2\t" + String2);
            sb.AppendLine("String3\t" + String3);
            return sb.ToString().Replace("\r\n", "\n");
        }

        public SimpleSerializableObject(string serializedString)
        {
            foreach (var line in serializedString.Split('\n'))
            {
                // キー + タブ + 値 の形で格納されているのを取り出す
                if (string.IsNullOrEmpty(line)) continue;
                var nameAndValue = line.Split('\t');
                var name = nameAndValue[0];
                var rawValue = nameAndValue[1];

                switch (name)
                {
                    case "Int1": Int1 = int.Parse(rawValue); break;
                    case "Int2": Int2 = int.Parse(rawValue); break;
                    case "Int3": Int3 = int.Parse(rawValue); break;
                    case "String1": String1 = rawValue; break;
                    case "String2": String2 = rawValue; break;
                    case "String3": String3 = rawValue; break;
                }
            }
        }
    }
}

(from https://github.com/chiepomme/SampleSerializer/blob/master/Serialization/SimpleSerializableObject.Serializer.cs)

これは、シリアライズ対象の SimpleSerializableObject を 以下のような Generator に通して自動生成したものになります。

using System;
using System.IO;
using System.Reflection;
using System.Text;

namespace SerializerGenerator
{
    class StaticStringSerializerGenerator
    {
        public void Generate(Type type)
        {
            File.WriteAllText(type.Name + ".Serializer.cs", Stringify(type));
        }

        public string Stringify(Type type)
        {
            var fields = type.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);

            // 本当はハードコードじゃなくて何かしらのテンプレートを使ってね!
            var sb = new StringBuilder();
            sb.AppendLine(@"// このファイルは StaticStringSerializerGenerator によって生成されました");
            sb.AppendLine(@"using System.Text;");
            sb.AppendLine();
            sb.AppendLine(@"namespace " + type.Namespace);
            sb.AppendLine(@"{");
            sb.AppendLine(@"    public partial class " + type.Name);
            sb.AppendLine(@"    {");
            sb.AppendLine(@"        public string Serialize()");
            sb.AppendLine(@"        {");
            sb.AppendLine(@"            var sb = new StringBuilder();");
            // 全フィールドの値を出力する部分を生成
            foreach (var field in fields)
            {
                sb.AppendFormat(@"            sb.AppendLine(""{0}\t"" + {0});", field.Name);
                sb.AppendLine();
            }
            sb.AppendLine(@"            return sb.ToString().Replace(""\r\n"", ""\n"");");
            sb.AppendLine(@"        }");
            sb.AppendLine();
            sb.AppendLine(@"        public " + type.Name + "(string serializedString)");
            sb.AppendLine(@"        {");
            sb.AppendLine(@"            foreach (var line in serializedString.Split('\n'))");
            sb.AppendLine(@"            {");
            sb.AppendLine(@"                if (string.IsNullOrEmpty(line)) continue;");
            sb.AppendLine(@"                var nameAndValue = line.Split('\t');");
            sb.AppendLine(@"                var name = nameAndValue[0];");
            sb.AppendLine(@"                var rawValue = nameAndValue[1];");
            sb.AppendLine();
            sb.AppendLine(@"                switch (name)");
            sb.AppendLine(@"                {");

            // 全フィールドのパース部分を生成
            foreach (var field in fields)
            {
                if (field.FieldType == typeof(int))
                {
                    sb.AppendFormat(@"                    case ""{0}"": {0} = int.Parse(rawValue); break;", field.Name);
                }
                else if (field.FieldType == typeof(string))
                {
                    sb.AppendFormat(@"                    case ""{0}"": {0} = rawValue; break;", field.Name);
                }
                sb.AppendLine();
            }

            sb.AppendLine(@"                }");
            sb.AppendLine(@"            }");
            sb.AppendLine(@"        }");
            sb.AppendLine(@"    }");
            sb.AppendLine(@"}");

            return sb.ToString();
        }
    }
}

(from https://github.com/chiepomme/SampleSerializer/blob/master/SerializerGenerator/StaticStringSerializerGenerator.cs)

コードはだいぶ読みづらくなってしまっていますが、先ほどのリフレクションを使わずにシリアライズするコードをテンプレートとして、個別のフィールドの部分を動的に生成するようにしたコードです。

このようにクラス毎のシリアライズのコードをファイルとしてそのまま生成してしまうというのが、静的コード生成の基本的な戦略になります。

リフレクションによるものと静的コード生成のパフォーマンスの比較

実際に上記の2つの方法+キャッシュ有りを比較したのが以下のグラフになります。

シリアライズ(1000回)

シリアライズ(100000回)

試行回数を問わず、静的コード生成バージョンはリフレクションを用いる物に比べて、最低でも2倍以上の速度が出るようになりました。

なお、シリアライザーのコードも計測コードもまとめて chiepomme/SampleSerializer にアップしてありますので、興味があれば是非ご覧ください。

おわりに

動的なものに比べるとこういった静的なコード生成は泥臭い印象がありますが、速度面で有利なことが多いです。その一方でコードのサイズは膨れてしまうので、場合によっては使用するべきではないシチュエーションもあると思います。このあたりはプロジェクトによるところなので、より理想に近い物を選んでいきたいですね。

ちなみに実際のプロダクトでは、シリアライズのフォーマットは MessagePack を用い、キーとしてフィールドの名前を使わず数字を使うなどの方法でさらに最適化していますが、基本的な考え方はこの記事の内容と同じです。シリアライズ周りのパフォーマンスで困っている方がいらっしゃったら何かの参考になればうれしいです。


t_fujino

「GameServerDevelopers Vol.1」に参加してきました!


こんにちは、Aimingエンジニアの藤野です!

5/28(土)に大阪で開催された、「GameServerDevelopers Vol.1」に参加しましたので、
その記事を書かせていただきます。

サーバ周りに特化した講演会

GameServerDevelopersということで、サーバに関するお話しを聞けるのが大きな特徴です!入社2カ月目の私でも理解できるような わかり易い導入から、負荷試験の種類と それぞれの実施方法について等の、とても濃いお話まで!色々盛り沢山でした!

弊社の山藤も登壇しました

GameServerDevelopersVol1_1
実はこの会、弊社の山藤も登壇させていただきました!お話しさせていただいた内容は、
Aimingで実際に使われている通信技術について!大規模MMORPGを動作させるために
必要な通信の基盤は、どんな設計をしているのかを紹介いたしました。

当日使用した資料です。

まとめ

今回が初の開催となる 「GameServerDevelopers Vol.1」 なんと100名以上の参加があり、これからも開催したいと締めくくりがありました!私もこの会で、新たな知見を得ることができ、知り合いが増え、グッズも貰い(これが目的じゃないですよ!)、本当に楽しい1日となりました!

個人的に、特に面白かったのは、負荷試験のお話しです。負荷試験とは、サーバ群の性能を図るテストです。組み上げたサーバ群が、どこまで耐えられるか?どこかに無駄がないか?等を知るために行います。
負荷試験って楽しくないですか?楽しいですよね!というところに共感しました!
本題は、サーバのスペックを正しく把握することで、必要最低限のサーバ構成にすることや、スムーズにスケーリングできること等のメリットがあるから、負荷試験大切!を学びました!

次回も是非、参加させていただきたいと思います!


s-kuroki

「聴いてすぐに試せる! Slackの便利な使い方講座」というタイトルで社内勉強会で話しました


こんにちは、エンジニアの黒木です。

先日、社内勉強会で「聴いてすぐに試せる! Slackの便利な使い方講座」というタイトルで話したので、その内容から抜粋して紹介します。

チャンネル一覧を整理して見やすくする

個人的に最重要だと思っている設定がこれです。

Slackを使いはじめると、割とすぐに入っているチャンネルの数が増えてきて、重要なチャンネルの話を集中して追いかけられない、という状態になりがちです。

  • 重要なチャンネルをStarして一覧の上部に表示する
  • 「Starしたチャンネル以外は未読がないときは非表示にする」設定で未読を消化しやすくする

この2つを行うことで、だいぶチャンネル一覧がスッキリします。

重要なチャンネルをStarして一覧の上部に表示する

times-skuroki___Aiming_Slack

チャンネルを開いた画面のこの位置にStarがあって、クリックするとStar/Unstarすることができます。Starされてない状態だと見えないので、カーソルをその位置に合わせてみてください。

「Starしたチャンネル以外は未読がないときは非表示にする」設定で未読を消化しやすくする

Slack

Slack

左上のメニューから、Preferences→Advanced Options→Channel Listの設定を「Hide any channels, etc., which have no unread activity, unless they are starred」に設定します。

チャンネルごとに通知の設定をする(Muteする、@here/@channel向け通知を受け取らないようにする)

状況を知っておくために他のチームのチャンネルに入ったりしても、@hereや@channelの対象になって、通知が来てしまって重要な通知が埋もれてしまう場合があります。また、ログをざっと見るためにだけ入っていて、新規発言を都度都度追いかける必要が無い場合があります。

前者には「@here/@channel向け通知を受け取らない」設定、後者にはMuteする設定が便利です。

貼り付けた画像_2016_05_23_20_46

貼り付けた画像_2016_05_23_20_49

設定したいチャンネルの画面を開いて、歯車のメニューからNotification Preferencesで開く画面で、どちらも設定できます。

1回だけ/定期的に自動で発言する

/remind というコマンドがあって、

/remind (誰に) (何と) (いつ)

という書式で書くことで、slackが自動で発言してくれます。たとえば以下の様な感じで設定できます。

  • /remind @s-kuroki ほげ 15:57
    • 自分に向けてのDirect Messageで15:57に「ほげ」と発言してくれる
  • /remind #foobar 今週も1週間がんばりましょう! every monday 10:00
    • #foobar というチャンネルに毎週月曜10:00に「今週も1週間がんばりましょう!」と発言してくれる

この書き方を覚えるだけでも結構便利ですが、他にも便利な指定の仕方はたくさんあります。

/remind

とだけ打つと、用例を教えてくれるので、より便利な使い方を知りたい人は見てみてください。

他に

  • チャンネルの検索
  • purposeやtopicの設定
  • 画像の貼り方

などを話しました。割と基本的な話も多いですが、使っていてもなかなか気が付かないこともあるので、そういうところをカバーしたいと思って話しました。

おまけ

Slackには自分たちのチーム独自のemojiが登録できるようになっていて、これをいろいろ登録しておくと、コミュニケーションを取るのに便利です。最後におまけで、私が登録したemojiの一部を紹介します。

Slack


PadrinoからRailsに移行しました


こんにちは、ソフトウェアエンジニアの藤井です。

今回は弊社で開発・運営を行っている 幻塔戦記グリフォン のWebAPIサーバーで使用していたPadrinoアプリケーションをRailsに移行した話を紹介します。

以下はチームのメンバーが発表したスライドです。

 

続きを読む


入社してからの1年間について発表しました

画像


はじめまして、ソフトウェアエンジニアの小林進です。
 
先日、大阪スタジオで開催されたAiming 飲み会#3 に登壇させていただき、ログレスチームのエンジニアの1年目と新しい取り組みについてお話をさせていただきました。

Aiming飲み会とは

AimingNomi#3_01

 
Aiming 飲み会はお酒を飲みながらゲーム開発について語り合う事を目的に開催される少しユルめの勉強会です。これまでは東京スタジオで開催していましたが、今回は初めて大阪スタジオ開催となりました。参加された方々とは開発について沢山お話しすることができ、とても勉強になりました。お越しくださった皆様、ありがとうございました!

 

こちらは登壇時に使用した資料です。
 

 
今回の発表ではクライアントのボトルネック解消に失敗した事と新しいアニメーションツールの導入の2つの事例について紹介させていただきました。前半はクライアントの描画ボトルネックの調査とそこから考えられる改善案、実装までを行い失敗した話を。後半では新しいアニメーションツールの導入から実装までについてお話させていただきました。

 
ゲーム会社に就職して1年目の様子はなかなか学生の頃には知ることはできなかったですが、この資料を作りながら振り返ると多くの事を学び経験できる濃い1年だったと感じました。

 
紹介となりますが、AimingではAiming飲み会やAimingStudyのような勉強会を今後も開催をしていく予定です。connpassのアカウントをお持ちで興味がおありの方は、コチラのURL より「メンバーになる」、もしくは「Join Group」をしていただけますと開催情報をより早く受け取ることができます。

 
次回開催も計画しておりますので、今後ともよろしくお願いします!

 

 


GWも近いので時間があるときに読んでおくとためになるサイトを紹介します!!


こんにちは、ソフトウェアエンジニアの平野です。

今回は GW も近いということで、時間があるときに読んでおくとためになるサイトを3つ紹介したいと思います。

Unity エディター拡張入門 (http://anchan828.github.io/editor-manual/web/)

「エディター拡張をすることで何ができるようになるの?」がとても分かりやすく書かれていて、エディター拡張をしてみたいと思っている方はぜひ一度読んでみるといいと思います。最近WEB無償版が公開されたようです。

任天堂 社長が訊くシリーズ (https://www.nintendo.co.jp/corporate/links/)

任天堂のさまざまなプロジェクトの制作エピソードが読めるサイトです。
ファイアーエムブレムシリーズが好きなので、ファイアーエムブレムの開発秘話が知れるだけでテンション高まりました(ちなみに私はカジュアルモード肯定派です)

電ファミニコゲーマー ゲームの歴史を紐解くシリーズ (http://news.denfaminicogamer.jp/category/projectbook)

今年の2月から連載が始まったシリーズで、ゲームに名を残している名作ゲームの製作エピソードが読めるサイトです。個人的にはコーエーの記事がおすすめです。「旦那のゲームを売るために離婚を辞さない」の言葉のインパクトはなかなかでした。

終わりに

今回は時間があるときに読んでおくとためになるサイトということで3つ紹介しました。
開発秘話や製作エピソードは一ユーザとして楽しく読みながらも、開発者として考えさせられる話とかもありますので、興味のある方はぜひ読んでみてください。