はじめに
こんにちは、ソーシャルゲーム事業部 Unityエンジニアの佐藤です。
今年は体重が9kg増加するという成長ぶりでした( ・`ω・´)
もうちょっとで桁が一つ増えるところまで来てしまいました...(´・ω・`)
この記事はカヤックUnityアドベントカレンダー2016 20日目の記事となります。
今回は、社内で使っているIDLについてご説明したいと思います。
Baalとは
BaalはKAYACで用いているIDL(インターフェース定義言語)です。
Unityで作ったクライアントアプリと、サーバーが通信する際のデータ形式の定義をしたものです。
ドキュメントの生成や、データ定義に基づいたC#ファイルの生成などを行います。
Baalを導入した経緯
Baal導入以前は、サーバーサイド担当のエンジニアとクライアント担当のエンジニアでAPIの設計を話して作るというフローでしたが、
- 設計の認識にズレが生じることがある
- エンドポイント毎に、APIを実行するクラスやレスポンスのデータ型、パーサーを書くのが大変
といった問題が度々発生しました。
それらの問題を解決するためにBaalが導入されました。
Baalは、APIやデータの型の定義する書式から、APIの実装やデータの型クラスファイル、パーサーを自動で生成することができます。
Baalの利用例
- データ型の定義(ステージの構成・敵の配置・アイテムの効果など)
- APIの定義(リクエスト・レスポンス)
Baalの使い方
Baalの定義例です。 ユーザーがログインするAPIのサンプルで紹介したいと思います。

定義を元に、C#のソースコードを生成したいと思います。
ランタイムはat.pkgs.baalを使用します。
生成されたファイルは下記となります。
// UserAPI_generated.cs
/*
* This file is auto-generated by program.
* Changes to this file may lost.
*/
using System.Collections.Generic;
using Kayac;
using Kayac.Net.Http;
using Models;
using Models.Data;
using Models.Data.Response;
namespace Models.Service
{
/// <summary>
/// ユーザーに関するAPI
/// </summary>
public sealed partial class UserAPI : APIBase<UserAPI.Api>
{
public enum Api
{
Login
}
/// <summary>
/// ログイン
/// このメソッドはリクエストをキャンセルできません
/// </summary>
public Operation<LoginResponse> Login(
System.String email,
System.String password
)
{
return Login(
email,
password,
CancellationToken.None
);
}
/// <summary>
/// ログイン
/// </summary>
public Operation<LoginResponse> Login(
System.String email,
System.String password,
CancellationToken cancellationToken
)
{
var context = GetContext(HttpMethod.Post, "api/login", Api.Login);
context.AddParameter("email", email);
context.AddParameter("password", password);
return context.GetResponseAsync<JsonResponse<LoginResponse>>(cancellationToken).
Select(resp => resp.Result.resultObject);
}
}
}
// LoginResponse_generated.cs
namespace Data.Response
{
public class LoginResponse
{
public System.Boolean result
{
get;
private set;
}
}
}
このようにBaalを用いてデータ定義をクラスにしたり、API定義を自動で実装したり...ということをKAYACではやっています。
また、データ型の継承もBaal定義で行うことが出来ます。
namespace Data.Request
{
abstract entity WithDeviceId
{
DeviceId: !string
}
entity LoginRequest
+= WithDeviceId // ←←DeviceIdがLoginRequestクラスに追加される
{
Email: !string;
Password: !string;
}
}
生成するファイルのテンプレートをカスタムできるので、プロジェクト毎に必要な形式を用意できます。
実務での利用
- GitHubを用いている場合は、Baal定義のプルリクエストを作り、サーバー/クライアントエンジニアでレビューする
- Git Subtreeを用いて、サーバーとクライアント、それぞれのリポジトリに定義を反映する
- Baal定義に問題がないか、自動テストをまわす
- Baal定義からのソースコード生成をJenkinsのジョブにする
といったようにプロジェクト毎にBaalのワークフローを拡張して開発速度や精度をあげる取り組みを行っています。
おわりに
明日はアファトのパフォーマンスチューニングについての記事です。
サクサク動くゲームってそれだけで楽しくなりますよね! ヒントは明日の記事にあるかと思いますので、ぜひ御覧ください!!