176
いろいろ見せますLord of Knights クライアント開発事例紹介 株式会社 Aiming リードソフトウェアエンジニア 細田幸治 2012/04/10

いろいろ見せますLord of Knightsのクライアント開発事例紹介

Embed Size (px)

DESCRIPTION

パソナテックエンジニアカフェで話すスライドです。 http://atnd.org/events/26591 Unityで作ったオンラインゲームの開発事例とC#を使った通信設計周りの話です。

Citation preview

Page 1: いろいろ見せますLord of Knightsのクライアント開発事例紹介

いろいろ見せます❤

Lord of Knights のクライアント開発事例紹介

株式会社 Aimingリードソフトウェアエンジニア

細田幸治2012/04/10

Page 2: いろいろ見せますLord of Knightsのクライアント開発事例紹介

こんばんは

Page 3: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ゲーム開発超楽しいで

す。

Page 4: いろいろ見せますLord of Knightsのクライアント開発事例紹介

そのなかでも

Page 5: いろいろ見せますLord of Knightsのクライアント開発事例紹介

オンラインゲーム開発

めっちゃ楽しい❤

Page 6: いろいろ見せますLord of Knightsのクライアント開発事例紹介

私は

Page 7: いろいろ見せますLord of Knightsのクライアント開発事例紹介

細田幸治といいます。

http://www.facebook.com/kouji.hosoda Lord of Knights のクライアント開発のチーフをしています。 以後お見知りおきを。

Page 8: いろいろ見せますLord of Knightsのクライアント開発事例紹介

というわけで

Page 9: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Lord of Knights開発事例紹介

Page 10: いろいろ見せますLord of Knightsのクライアント開発事例紹介

話すこと

● ゲーム紹介 ● 開発あるあると改善の話 ● Unity+HTML で作るハイブリッドアプリ

● C#を活用した非同期通信アプリ

Page 11: いろいろ見せますLord of Knightsのクライアント開発事例紹介

時間があれば

● AppleStoreの審査あれこれ

Page 12: いろいろ見せますLord of Knightsのクライアント開発事例紹介

この発表のターゲット

● ゲーム開発ってどうやってるのか興味がある人

● ある程度 Unity & C# を触ってる人

● これからオンラインゲーム作りたい人

Page 13: いろいろ見せますLord of Knightsのクライアント開発事例紹介

はじめに

Page 14: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ゲーム紹介

Page 15: いろいろ見せますLord of Knightsのクライアント開発事例紹介
Page 16: いろいろ見せますLord of Knightsのクライアント開発事例紹介
Page 17: いろいろ見せますLord of Knightsのクライアント開発事例紹介

どんなゲーム?

カードを強化して戦うストラテジー RPG

● メインプレイは内政、カード強化、バトルのサイクル

● 多人数で1つのマップを共有する戦略ゲーム

○同盟を組んで協力プレイ

○他の同盟と競争して目標となる拠点を奪い合

Page 18: いろいろ見せますLord of Knightsのクライアント開発事例紹介

どんなゲーム?

おかげさまでApp Storeの

→トップ25

→トップ無料

で5位になりました ※2012/04/07現在

Page 19: いろいろ見せますLord of Knightsのクライアント開発事例紹介

どんなゲーム?

詳しくは Web へ

http://lordofknights.jp

Page 20: いろいろ見せますLord of Knightsのクライアント開発事例紹介

開発あるあると改善の話

Page 21: いろいろ見せますLord of Knightsのクライアント開発事例紹介

まず

Page 22: いろいろ見せますLord of Knightsのクライアント開発事例紹介

開発の前提

Page 23: いろいろ見せますLord of Knightsのクライアント開発事例紹介

大事なことは

● チームみんなで楽しく開発すること

● そのための工夫や改善をひたすら頑張る

○言いだしっぺが主導して頑張る

● 何があっても楽しく、あわてない

Page 24: いろいろ見せますLord of Knightsのクライアント開発事例紹介

具体的事例紹介

Page 25: いろいろ見せますLord of Knightsのクライアント開発事例紹介

開発規模

● クライアント開発 3-8人

● サーバー開発約 5人

● 企画 3人

● デザイン 3人

の約 20人でリリースまで 8ヶ月半

現在はリリースされたので運営とマーケティングも加わりもっと増えてる

Page 26: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題1

● 企画とエンジニアのすれ違いが多くて仲が悪い

● 部署ごとに部屋を区切られていてコミュニケー

ションが取りづらい

Page 27: いろいろ見せますLord of Knightsのクライアント開発事例紹介

あるある

Page 28: いろいろ見せますLord of Knightsのクライアント開発事例紹介

これは最初から対策

Page 29: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

● 企画、エンジニア、デザイン、運営など必要なメンバー全員で1チーム

● メンバーの席は近くする

Page 30: いろいろ見せますLord of Knightsのクライアント開発事例紹介

すごい

リーダー

チームの席は一緒

● すごいリーダー(総責任者、仕様判断、運営判断、なんでも判断)が中心

Page 31: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

● 企画リーダーとエンジニアリーダーがその近く

すごい

リーダー エンジニ

リーダー

企画リー

ダー

Page 32: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

● UIデザイナーが企画リーダーの近く

すごい

リーダー

UIデザ

イナー

エンジニ

リーダー

企画リー

ダー

Page 33: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

● テクニカルアーティストはUIデザイナーとエンジニアの近く

すごい

リーダー

UIデザ

イナー

エンジニ

リーダー

企画リー

ダー

TA

Page 34: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

● 運営が企画とリーダーの近く

すごい

リーダー

運営

UIデザ

イナー

エンジニ

リーダー

企画リー

ダー

TA

Page 35: いろいろ見せますLord of Knightsのクライアント開発事例紹介

すごい

リーダー

運営

UIデザ

イナー

エンジニ

リーダー

企画リー

ダー

チームの席は一緒

● エンジニアや企画のメンバーは各リーダーの近く

エンジ

ニア

エンジ

ニア

企画

企画

TA

Page 36: いろいろ見せますLord of Knightsのクライアント開発事例紹介

すごい

リーダー

運営

UIデザ

イナー

● 新人は各リーダーの近く

エンジニ

リーダー

企画リー

ダー

チームの席は一緒

エンジ

ニア

エンジ

ニア

企画

企画

TA

新人

新人

Page 37: いろいろ見せますLord of Knightsのクライアント開発事例紹介

チームの席は一緒

結果 ● 必要な人にすぐ判断を仰げる

● 関連する会話が自然と耳に入る

● 新人が放置されにくい

結果

Page 38: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 39: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題2

● 他のメンバーが何をやっているか分からない

● 問題があったときに誰に相談したらいいか分か

らない

?

Page 40: いろいろ見せますLord of Knightsのクライアント開発事例紹介

あるある

Page 41: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ありました

Page 42: いろいろ見せますLord of Knightsのクライアント開発事例紹介

朝会

Page 43: いろいろ見せますLord of Knightsのクライアント開発事例紹介

朝会

● チーム全員で朝一で集まって立ったまま10-15分で

● 当日やること、分かってる懸念点を報告

● 難しい話はしない

○長くなるなら後で個別に話し合う

Page 44: いろいろ見せますLord of Knightsのクライアント開発事例紹介

朝会

結果

● 全員の動きが把握できた

● 問題はチームで共有

● 短時間に出来れば特にデメリットは無い

結果

Page 45: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 46: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題3

● 朝会の時に昨日やったことを忘れている

● 問題報告が遅れる

● 残業が多い

Page 47: いろいろ見せますLord of Knightsのクライアント開発事例紹介

あるある

Page 48: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ありました

Page 49: いろいろ見せますLord of Knightsのクライアント開発事例紹介

夕会

Page 50: いろいろ見せますLord of Knightsのクライアント開発事例紹介

夕会

● チーム全員で終業時間前に集まって立ったまま10-15分で

● 忘れないうちに報告

○当日達成できたこと

○出た問題点

●残業の必要性を報告

○その日のうちにやらなくていいと判断したら帰る

Page 51: いろいろ見せますLord of Knightsのクライアント開発事例紹介

夕会

結果 ● 夕会で報告が済むので次の日から朝会が短く

なった ● 問題共有の漏れが減り、共有も早くなった

● 残業が減った!

結果

Page 52: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 53: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題4

リモート会社との仕事をしている時 ● チャットやメールだけだとお互い仕事の進みが

見えず足並みがそろわない ● 問題発見が遅れる

??

Page 54: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ある(ry

Page 55: いろいろ見せますLord of Knightsのクライアント開発事例紹介

週例ビデオチャット会議

● お互い顔を見ながら30分以内で簡潔に

● 進捗報告と問題共有、改善共有

● 雑談も交えつつ

Page 56: いろいろ見せますLord of Knightsのクライアント開発事例紹介

週例ビデオチャット会議

結果 ● 合意が作りやすい

○すれ違いが減る

● 見えていなかった問題がぽろっとでてくる

● 仲良くなれる

結果

Page 57: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 58: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題5

● どの実装を優先すべきか分からない

● 実装中に仕様抜け(必要なのに決まってない仕

様があること)がぽろぽろでる ?

Page 59: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ある(ry

Page 60: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ユーザー体験をリスト化

Page 61: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ユーザー体験をリスト化

● ユーザーの体験(ストーリー)ベースで出来ることをリストアップ

● 上記をマイルストーンごとにまとめ、いつどんな

体験が出来るかが一覧できる ● すごいリーダーが優先順位をつけてどれが大事

か決定する

Page 62: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ユーザー体験をリスト化

結果 ● 次にやることが明確になった

● ストーリーを書く段階で仕様抜けにあるていど

気づける ● これをマスターストーリーリストって言うらしい

結果

Page 63: いろいろ見せますLord of Knightsのクライアント開発事例紹介

マスターストーリーリスト

こんなの

(ユーザーが)何をどうできるというように具体的に書く

Page 64: いろいろ見せますLord of Knightsのクライアント開発事例紹介

マスターストーリーリスト

こんなの

フローを工夫しないと管理が大変

Page 65: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 66: いろいろ見せますLord of Knightsのクライアント開発事例紹介

問題6

● スケジュール通りに終わらない

● デスマーチになる

Page 67: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ある(ry

Page 68: いろいろ見せますLord of Knightsのクライアント開発事例紹介

タスクの増加・消化を可視化

Page 69: いろいろ見せますLord of Knightsのクライアント開発事例紹介

タスクの増加・消化を可視化

● マイルストーン終了までに必要な総タスク数をカウント

● 毎週タスク数をカウントしてグラフ化

○総タスクの増減

○消化タスク数

○週当たりの平均値

● 総タスクが増えたら、その理由を記録

Page 70: いろいろ見せますLord of Knightsのクライアント開発事例紹介

タスクの増加・消化を可視化

結果● 遅れはじめたらすぐ分かるようになった

● いつごろ終わるか予測が立つようになった

● 何で遅れたか把握でき、不安が減った

● リリースバーンダウンチャートって言うらしい

結果

Page 71: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

Page 72: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

スケジュールが延びた実例

Page 73: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート) タスク25個からスタート

Page 74: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート) 線形的に増えて

Page 75: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

最終的に約70個に

Page 76: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

約3倍のずれヒャッハー!!

Page 77: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

でも週の消化数は平均して7出てる

Page 78: いろいろ見せますLord of Knightsのクライアント開発事例紹介

リリースバーンダウンチャートこんなの(OBTリリースまでの実際のチャート)

平均速度からリリースを予測可能

Page 79: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ここまでのまとめ

Page 80: いろいろ見せますLord of Knightsのクライアント開発事例紹介

結果

アジャイル開発に

なりました

Page 81: いろいろ見せますLord of Knightsのクライアント開発事例紹介

現在の問題

いまはリリース直後で作業の割り込みが多く、優先度がころころ変わってる↓中長期のスケジュールが立っていない↓どうしたらいいか試行錯誤中

Page 82: いろいろ見せますLord of Knightsのクライアント開発事例紹介

大事なことは?

● リスクの早期発見と改善が基本セット

● チームみんなで作るという意識(自発的である)

● 何があっても楽しく、あわてない

● 何でも言えるチームの空気

上記が実現できれば細かい手法は問わない

Page 83: いろいろ見せますLord of Knightsのクライアント開発事例紹介

開発プロセスの話はここ

まで

Page 84: いろいろ見せますLord of Knightsのクライアント開発事例紹介

続いて技術の話

Page 85: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Unity! Unity!

Page 86: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Unity + HTMLで作る

ハイブリッドアプリ

Page 87: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Unity×HTMLな理由

● Unity で UI 作るの大変!

● 内政、マップ、レポート、メール、ショップ、合成、

カード・・・・・・など 40画面以上! ● リスト系など動きが少ない画面はHTMLの方が

作りやすい!

Page 88: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTMLを使うメリット

ぱっと見区別できないぐらい自然

HTML画面Unity画面

Page 89: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTMLを使うメリットその2

リリース後のアップデートがしやすい● 審査なしでアップデート可能

○ キャンペーンページなどの自由が利きやすい

HTML画面

Page 90: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTMLを使うメリットその3

自由文字入力ができる● iPhone 上でフォントに使えるテクスチャサイズ

に制限がある(EZ GUI)○ 1つのフォントごとに 2048*2048 ピクセルのテクスチャに

収める必要がある(iPhone4以降) ● HTML だと上記のような制限がない

○ チャットなど自由入力出来る画面は HTML で作成

Page 91: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTMLを使うデメリット

● ローディングが長い

● 反応が遅い

○ どうしてもユーザー体験が落ちる

● メモリーを喰う

○ ゲーム内メールなどのリストを追加読み込みし続けると

突然落ちたりする

● エディターで確認できないところがある

○ 後で説明する Unity と HTML との連携部分

Page 92: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTMLとUnityの連携仕様

● 連携とは

○ HTML 側から Unity の関数を呼び出す仕組みの事

● なにに使うか?

○ クエストの達成判定

○ サーバーと Unity 内モデルのデータ同期

○ Unity の画面遷移やUIの操作

Page 93: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

● 実装方法

○ Native Plugin として実装

○ Objective-C の UIWebView を利用

UIWindow *window =[[UIApplication sharedApplication] keyWindow]; // 基本クラスのインスタンス作るだけでOK

UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0,0,width,height)];

[window addSubview:webView];

Page 94: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

shouldStartLoadWithRequest を使ってクエリスト

リングをパース クエリストリングとは

URL の後ろにつく ?aho=foo&hoge=bar みたいなやつ UIWebViewNavigationType が以下の場合に処理

UIWebViewNavigationTypeFormSubmittedUIWebViewNavigationTypeLinkClickedUIWebViewNavigationTypeOther

Page 95: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

shouldStartLoadWithRequest を使ってクエリスト

リングをパース パース処理部分 NSString *query = [[request URL] query];if(query == nil) return YES;NSArray *parsedStrings = [query componentsSeparatedByString:@"&"]; for (NSString *q in parsedStrings){

char* key = [[[q componentsSeparatedByString:@"="]objectAtIndex:0]

}

Page 96: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

UnitySendMessage でパースしたデータを送信

Objective-C側でメッセージ送信

Unity側でメッセージ受信

if(strcmp(key,"change_scene") == 0){

UnitySendMessage(gameObjectName, "ChangeScene", value);}

void ChangeScene(string targetScneneName){

Appllication.LoadLevel(targetScneneName);}

Page 97: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

● フォルダ構成

○ Plugins/iOS 以下に Objective-C のコードを配置

○ ビルド時に Unity が自動的に Xcode のプロジェクトにコ

ピーしてくれる

Page 98: いろいろ見せますLord of Knightsのクライアント開発事例紹介

HTML×Unity 実装

● ブラウザが操作不能になる問題が出た

○ Unity 側が自動生成する AppCotroller.mm の描画フラ

グを変更(@Unity3.4) ○ #define USE_DISPLAY_LINK_IF_AVAILABLE 0

Page 99: いろいろ見せますLord of Knightsのクライアント開発事例紹介

C# を活用した

非同期通信アプリ

Page 100: いろいろ見せますLord of Knightsのクライアント開発事例紹介

非同期通信って何?

サーバーと通信する時に結果を待っている間フリーズしてプログラムが止まっているのが同期通信。サーバーと通信する時に、結果を待たずにプログラムは続行し、結果が返ってきたら通信処理の続きが実行されるようにするのが非同期通信。 ゲームなどではフリーズを防ぐために通信処理は非同期通信で実装する必要がある。

Page 101: いろいろ見せますLord of Knightsのクライアント開発事例紹介

非同期通信って何?

ようするに

めんどくさい

Page 102: いろいろ見せますLord of Knightsのクライアント開発事例紹介

非同期通信アプリの設計指針

● 通信の実装を気にしたくない

● 処理を直感的に書きたい

● エラーもあまり気にしたくない

● サーバー実装に依存したくない

● 簡単に View に反映させたい

Page 103: いろいろ見せますLord of Knightsのクライアント開発事例紹介

なぜそうするか

Page 104: いろいろ見せますLord of Knightsのクライアント開発事例紹介

1つ1つ解説します

Page 105: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

よくあること ● 仕様が変わる

● 仕様変わったら通信実装も色々変わる

○ APIのインターフェイスの修正

○ データのシリアライズ

○ バリデーション

良くあること

Page 106: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

結果 ● 表示部分の実装、確認がなかなかできない

● バグりやすい

↓仕様変更、追加コストが高い ってなってしまう。

結果

Page 107: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

そこで

Page 108: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

通信実装コードの自動生成

Page 109: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

通信実装コードの自動生成● https://github.com/ppcuni/rpcoder

※ 動かすには LitJSON の微修正必要なので参考程度に ● 定義ファイルから実装コードを自動生成する

ツール ● アプリケーション層で通信実装を気にする必要

はないようになってる

Page 110: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

Page 111: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

APIを定義

Page 112: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

エンドポイントURL

Page 113: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

Method

Page 114: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

引数いろいろ

Page 115: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

定義ファイル# ユーザ登録しログインする

RPCoder.function "registerUser" do |f| f.path = "/startup/regist.php" # エンドポイント URL

f.method = "POST" # 通信メソッド

f.add_param :invitation_code, "String",{:require => false} #招待コード

f.add_param :user_name, "String" # 登録ユーザ名

f.add_param :card_number, "int" # 初期カード番号

f.add_param :direction_id, "int" # 方角ID

f.add_return_type :login_user_info, "LoginUserInfo" # ユーザーの全情報

f.description = "ユーザ登録する"

end

戻り値

Page 116: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

自動生成されるもの ● API のインターフェイスクラス

● API の実装クラス

● API の Mock クラス

● 型の実装クラス

● 型のシリアライザ、デシリアライザ

C#

Page 117: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信の実装を気にしたくない

色々めんどくさいところ作ってくれるバグがあってもテンプレート直せばOK

Page 118: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 119: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

よくあること ● リクエストとレスポンスの処理が分離している

● 非同期処理を連続して行うときにカオスになる

良くあること

Page 120: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

結果 ● コードの見通しが悪い

● 通信時に何処で何が起きてるか分からない

● バグりやすい

↓仕様変更、追加コストが高い ってなってしまう。

結果

Page 121: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

そこで

Page 122: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

メソッドチェインで書けるように

Page 123: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

記述例

var task = IncrementAsync(1)// タスク完了時に呼ばれる完了処理(2を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result))// ↑のタスク成功時に別のタスクを繋げる

.ContinueWithTask<int>(IncrementAsync)// ↑のタスク完了時に呼ばれる完了処理(3を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result));

Page 124: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

記述例

var task = IncrementAsync(1)// タスク完了時に呼ばれる完了処理(2を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result))// ↑のタスク成功時に別のタスクを繋げる

.ContinueWithTask<int>(IncrementAsync)// ↑のタスク完了時に呼ばれる完了処理(3を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result));

非同期呼び出し

Page 125: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

記述例

var task = IncrementAsync(1)// タスク完了時に呼ばれる完了処理(2を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result))// ↑のタスク成功時に別のタスクを繋げる

.ContinueWithTask<int>(IncrementAsync)// ↑のタスク完了時に呼ばれる完了処理(3を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result));

非同期結果受け取り

Page 126: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

記述例

var task = IncrementAsync(1)// タスク完了時に呼ばれる完了処理(2を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result))// ↑のタスク成功時に別のタスクを繋げる

.ContinueWithTask<int>(IncrementAsync)// ↑のタスク完了時に呼ばれる完了処理(3を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result));

続けて行う非同期処理

Page 127: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

記述例

var task = IncrementAsync(1)// タスク完了時に呼ばれる完了処理(2を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result))// ↑のタスク成功時に別のタスクを繋げる

.ContinueWithTask<int>(IncrementAsync)// ↑のタスク完了時に呼ばれる完了処理(3を出力)

.OnComplete(t => UnityEngine.Debug.Log(t.Result));

非同期結果受け取り

Page 128: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

すっきり

Page 129: いろいろ見せますLord of Knightsのクライアント開発事例紹介

処理を直感的に書きたい

実装的には 非同期処理用のクラスを作成● 内部処理は yield を利用したコルーチン

● コルーチンの完了をメソッドチェインで書ける

● 次のコルーチンをメソッドチェインで繋げる

Page 130: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 131: いろいろ見せますLord of Knightsのクライアント開発事例紹介

エラーもあまり気にしたくない

よくある ● API ごとにエラー処理が分散している

● 連続してエラーが起きたときに最後のエラーし

か分からない

良くあること

Page 132: いろいろ見せますLord of Knightsのクライアント開発事例紹介

エラーもあまり気にしたくない

結果 ● エラー実装がめんどくさい

● バグ調べにくい

↓仕様変更、追加コストが高い ってなってしまう。

結果

Page 133: いろいろ見せますLord of Knightsのクライアント開発事例紹介

エラーもあまり気にしたくない

そこで

Page 134: いろいろ見せますLord of Knightsのクライアント開発事例紹介

エラーもあまり気にしたくない

● すべての非同期処理を共通化

○ 根っこ部分で try/catch してエラーハンドリング

○ エラーダイアログを出したりする処理も共通化

● 個別エラー処理も可能に

○ エラーが複数発生したらキューにして全エラーを保持

○ エラーはタスクをまたいで次のタスクに伝播、後でチェッ

クできる

Page 135: いろいろ見せますLord of Knightsのクライアント開発事例紹介

エラーもあまり気にしたくない

View はだいたい正常系だけ書けば OK

Page 136: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 137: いろいろ見せますLord of Knightsのクライアント開発事例紹介

サーバー実装に依存したくない

よくあること ● サーバーの実装が完了しないと画面確認できな

い ● 通信エラーが起きたときの再現が取れない

良くあること

Page 138: いろいろ見せますLord of Knightsのクライアント開発事例紹介

結果 ● 実装のFixが延び延びになる

● バグ調べにくい

↓仕様変更、追加コストが高い ってなってしまう。

結果

サーバー実装に依存したくない

Page 139: いろいろ見せますLord of Knightsのクライアント開発事例紹介

そこで

サーバー実装に依存したくない

Page 140: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Mock

サーバー実装に依存したくない

Page 141: いろいろ見せますLord of Knightsのクライアント開発事例紹介

サーバー実装に依存したくない

Mock とは

● 擬似サーバー

● クライアントだけで完結

● ソースの変更無しで

サーバーと切り替えられる

クライアント

Mock

Server

Page 142: いろいろ見せますLord of Knightsのクライアント開発事例紹介

サーバー実装に依存したくない

Mock を使うと

● サーバー実装スケジュールとの依存が少ない

● 異常系の確認も手軽にできる

Page 143: いろいろ見せますLord of Knightsのクライアント開発事例紹介

サーバー実装に依存したくない

Mock 実装の例

Page 144: いろいろ見せますLord of Knightsのクライアント開発事例紹介

しばらくサーバーいらず

サーバー実装に依存したくない

Page 145: いろいろ見せますLord of Knightsのクライアント開発事例紹介

Page 146: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい

よくあること ● View で Polling してデータをチェック→反映

○ GameObject の Update の中でチェックする感じ

○ Unity3.5 のプッシュ通知の初期化周りとかがそんな感じ

良くあること

Page 147: いろいろ見せますLord of Knightsのクライアント開発事例紹介

結果 ● チェック頻度が高いと負荷が高い

● チェック頻度が低いと画面反映が遅れる

● チェックコード自体書きたくない

↓余計な負荷、ユーザー・エンジニア体験の悪化 ってなってしまう。

結果

簡単に View に反映させたい

Page 148: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい

そこで

Page 149: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい

イベントドリブンで View を更新

Page 150: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい実装例

public class CityModel{

// 資源の増減通知

public event Action<ResourceStatus> Updated;} public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void Start(){

// 資源の増減通知を購読、解除設定

_cityModel.Updated += OnResourceUpdated;base.AddDisposable(_cityModel, x => x.Updated -= OnResourceUpdated);

}}

Page 151: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい実装例

public class CityModel{

// 資源の増減通知

public event Action<ResourceStatus> Updated;} public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void Start(){

// 資源の増減通知を購読、解除設定

_cityModel.Updated += OnResourceUpdated;base.AddDisposable(_cityModel, x => x.Updated -= OnResourceUpdated);

}}

イベントを定義

Page 152: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい実装例

public class CityModel{

// 資源の増減通知

public event Action<ResourceStatus> Updated;} public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void Start(){

// 資源の増減通知を購読、解除設定

_cityModel.Updated += OnResourceUpdated;base.AddDisposable(_cityModel, x => x.Updated -= OnResourceUpdated);

}}

+= でイベント購読開始

Page 153: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい実装例

public class CityModel{

// 資源の増減通知

public event Action<ResourceStatus> Updated;} public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void Start(){

// 資源の増減通知を購読、解除設定

_cityModel.Updated += OnResourceUpdated;base.AddDisposable(_cityModel, x => x.Updated -= OnResourceUpdated);

}}

イベント購読解除を予約

Page 154: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたいイベントを受け取った時の処理

public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void OnResourceUpdated(ResourceStatus resource){

// テキストフィールド更新

_currentManaText.Text = resource.CurrentMana.ToString();}

}

Page 155: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたいイベントを受け取った時の処理

public class CityView : Aiming.TSS.Infrastructure.EventDrivenBehavior{

void OnResourceUpdated(ResourceStatus resource){

// テキストフィールド更新

_currentManaText.Text = resource.CurrentMana.ToString();}

}

表示処理だけ書けばOK

Page 156: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい

● View の作成時に Model の変更イベントを購読

● View の破棄、非表示時にイベント購読を解除

● 購読と解除は近くに記述できるようにする

Page 157: いろいろ見せますLord of Knightsのクライアント開発事例紹介

簡単に View に反映させたい

すっきり

Page 158: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ちなみに通信実装は

Page 159: いろいろ見せますLord of Knightsのクライアント開発事例紹介

通信実装で使ったもの

● 通信処理は Unity の WWW クラスを利用

● データフォーマットは JSON

● JSON のパースに LitJSON を改良して利用

○ http://sourceforge.jp/projects/sfnet_litjson/○ ライセンスがゆるい

○ ソースコードがフルオープン

Page 160: いろいろ見せますLord of Knightsのクライアント開発事例紹介

まとめると

Page 161: いろいろ見せますLord of Knightsのクライアント開発事例紹介

まとめ

● 自動生成いいね

● 直感的に書けるのいいね

● エラーは簡単に処理できるのいいね

● Mock いいね

● イベントいいね

Page 162: いろいろ見せますLord of Knightsのクライアント開発事例紹介

以上技術の話でした

Page 163: いろいろ見せますLord of Knightsのクライアント開発事例紹介

最後に

とにかく楽しむ

どんなトラブルも懸念事項も前向きに取り組めば楽しいクエストになります

Page 164: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ゲーム開発超楽しい❤

Page 165: いろいろ見せますLord of Knightsのクライアント開発事例紹介

ご清聴ありがとうございました

Page 166: いろいろ見せますLord of Knightsのクライアント開発事例紹介

あそびにきてね!

株式会社 Aiming はオフィス見学を

いつでも受け付けています。 興味がある方はお気軽にご連絡ください。

Page 167: いろいろ見せますLord of Knightsのクライアント開発事例紹介
Page 168: いろいろ見せますLord of Knightsのクライアント開発事例紹介

おまけ

Page 169: いろいろ見せますLord of Knightsのクライアント開発事例紹介

AppleStoreの審査あれこれ

初めての iPhone アプリリリースだった ノウハウがなかったので試行錯誤

Page 170: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

リリースまでにリジェクト3回されました リジェクト理由その1● キャッシュファイルの保存場所が悪くてアウト!

○永続化用と一時用があるので気をつける

○保存場所を直して解決

Page 171: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

リジェクト理由その2● レビュアーが想定通りに行動しなくてアウト!

○審査専用アカウントかどうかで、審査用サーバーか本番

サーバーかをスイッチしていたが、レビュアーが専用アカウントを使ってくれなかった

○クライアントのバージョンでサーバーをスイッチするようにして解決

Page 172: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

リジェクト理由その3● 審査中にメンテをしたらレビュアーがログインで

きなくなってアウト○In Reviewになったらメンテを予定していたとしてもリスケ

ジュールする

○次からワークフローに落とし込んで解決

Page 173: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

どのくらいで通るの?● だいたい審査出してから約5営業日で審査開始

(In Review)、だいたいその数時間後に結果出る ● 場合によってはIn Reviewのまま1日過ぎることも

あるので油断しない

Page 174: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

どういう判断基準?● 審査のたびに判断基準がまちまち

● 深く見られる時もあれば一瞬でOKでる時も

Page 175: いろいろ見せますLord of Knightsのクライアント開発事例紹介

審査について

とにかく地雷が多いので● なるべく早く最初の審査をだす

● 早くたくさん地雷を踏む

● 審査提出時は2人以上でダブルチェック

Page 176: いろいろ見せますLord of Knightsのクライアント開発事例紹介

おわり