【アップデート】PhotonCloud より安価に便利に利用できるリアルタイム対戦サーバを公開
みなさんこんにちは。GS2の丹羽です。
先週に引き続き、今週も重要なアップデートが行われましたので、お知らせします。
今週のアップデート
GS2-Realtime - リアルタイム対戦サーバを追加
対戦や協力プレイで使用できるリアルタイム対戦サーバが追加されました。
このサーバでは最大100人(今後さらに引き上げる計画あり)が同じゲームサーバに接続し、リアルタイムにデータ交換を行えるようにします。
今回のリリース時点では、簡易的なプレイヤー間でデータ同期をする仕組みと、プレイヤー間でデータ送受信を行う仕組みを提供します。
今後のアップデートで任意のサーバプログラムを配置できるようにして、MMORPGのようにサーバサイドで一定間隔でエネミーをポップさせたり、レイドバトルでボスの体力の状態をサーバ側で管理できるようにします。
CCU管理不要
一般的なリアルタイム対戦サーバはCCU(同時接続数)のキャパシティ管理が必要でした。
しかし、GS2 はゲームルームの起動時間1分あたりの料金で計算され、CCUを管理する必要はありません。
1分あたりの料金はサーバの性能によって変動し、サーバの性能は同時接続数やデータの送信間隔によって適切な性能の設定が変わってきます。目安として『8人対戦で毎秒2回256バイトのデータをルーム内の全プレイヤーに送信する』ユースケースで、最も安価な realtime1.nano(0.04円/分) で提供可能です。
Photon Cloud より安価に利用可能
Photon Cloud は 20CCU & 60GB の通信が無料枠として設定されています。
GS2 の無料枠は realtime1.nano であれば 50万分のルーム起動時間に相当します。これは11のゲームルームを常時起動できる時間に相当します。単純計算で2人対戦であれば22CCU。4人対戦ゲームであれば44CCUとなりますが、実際は常時起動しておくわけではなく対戦を開始してから対戦を終了するまでのルーム起動時間に対してしか費用が発生しませんので、実際は例示したCCUよりもっと多くの同時対戦をホストできます。
さらに、日本リージョンにおける 1GBあたりの通信料金は Photon Cloud では 18.25円 ですが、GS2-Realtime は 15円 で利用できます。
GS2-Matchmaking に GS2-Realtime 連携機能を追加
GS2-Matchmaking の機能が拡張され、マッチメイキング開始時やマッチメイキング完了時に GS2-Realtime のルームを作成できるようになりました。
マッチメイキングをしながらチャットをできるようにしたい場合や、マッチメイキングが完了したあとシームレスに対戦・協力プレイに繋ぎたいときに使用できます。
来月のマイルストーンを公開
8月のアップデート予定を公開しました。
ざっくりとタスクをご紹介します。
- GS2-Script のコードや、GS2-Deploy のテンプレート、各サービスのマスターデータを GitHub リポジトリから取得して反映できるように
- GS2-Exchange 陳列棚を伴わないリソース交換(★1素材x10で★2素材1に交換できる。アイテムAを売却すると500Gで売れる)
- GS2-Inventory の機能拡張。所持数量上限を超えたときに別スロットにアイテムを追加で所持できるように
- GS2-Inbox の機能拡張。プレゼント開封時の処理が現在は GS2-Script の実行のみだが、スクリプトを介さずGS2の各種リソースの付与を行えるように
- Unreal Engine 4 向け SDK の提供開始
※ あくまで予定ですので、変更がある可能性があることをご了承ください。
お気軽にご相談ください
サイト内の右下に設置されたチャットで話しかければ、GS2のスタッフがすぐに対応いたします。
GS2 についての質問や、GS2 をどのように活用するべきかのご相談などでご活用ください。
また、ゲームの仕様を共有いただき どの部分で GS2 を活用いただけるか GS2 がアーキテクトをしてご提案もしています。機密保持契約を結んでの対応も可能です。
みなさんがゲームのコアバリューを磨くことに注力できる環境づくりを進めていますので、ぜひご活用ください。
【アップデート】WebSocket による常時接続通信に対応・プッシュ通知に対応
みなさんこんにちは。GS2の丹羽です。
ベータテストを開始して1週間が経過しました。既に多くのユーザに評価いただき、感謝しております。
これから、定期的にサービスのアップデート情報を皆さんにお届けすることにしました。
ぜひ今後のご参考にしていただければと思います。
今週のアップデート
WebSocket による常時接続通信に対応
ベータテスト開始時点ではすべての通信は HTTP ベースの通信のみ対応としていました。このアップデートにより、新たに常時接続ベースの通信が利用できるようになりました。
WebSocket は HTTP と比較して通信のたびに再接続を行わないことから通信の応答速度の向上が期待できます。
あわせて公開した GS2-SDK for Unity 2019.7.2 ではデフォルトの通信プロトコルが WebSocket に変更されています。
サーバイベント通知に対応
WebSocket による常時接続ができるようになり、サーバからクライアントに対してメッセージを送信できるようになります。
GS2-Matchmaking では【対戦相手が見つかった場合】【マッチメイキング中に対戦相手が離脱した場合】【マッチメイキングが成立した場合】の3種類のイベントがプッシュ通知で受け取れるようになります。
GS2-Mission では クエストクリア回数などのカウンターを操作し【ミッションのタスクを達成した場合】に通知を受け取れるようになります。
GS2-JobQueue では【ジョブキューに新しいジョブが追加された時】にプッシュ通知を受け取れるようになります。
この通知機能は Firebase を利用したモバイルプッシュ通知への転送機能があります。
これを利用すれば、【マッチメイキングが成立した時】にアプリを終了した場合、モバイルプッシュ通知で知らせる ということが実現できます。
通知の種類ごとに転送を利用するかを設定できますので、重要度の高い通知のみ有効にすることをおすすめします。
GS2 の採用に迷ったら?
ゲームの仕様をお聞かせ願えれば、どのようにGS2のサービスを活用すればいいかご提案します。
その際、機密保持契約が必要な場合も都度対応可能です。
検証レベルの評価、リリース時期未定のタイトルであっても問題ございません。まずは contact@gs2.io までお気軽にご相談ください。
GS2 に関するブログエントリー募集
Qiita や ブログ などで 『GS2 を触ってみた』といったエントリーを書いていただけませんでしょうか。ベータリリース後それらしい記事が出てきておらず少しさみしいです…。ぜひご支援いただけますと助かります!
Vue + TS に触れて2週間でシングルページアプリケーションを作ってリリースした話
みなさん、こんにちは。GS2の丹羽です。
本日 Game Server Services は次世代版のベータテストを開始しました。
これまで提供していた GS2 を GS2 Classic と呼び、次世代版 GS2 を単に GS2 と呼びます。
GS2 のリリースにあたっては非常に多くの新しいチャレンジを行いました。
それについては少しずつブログや登壇を通じて皆さんにお伝えしていきたいと思います。
今回は、GS2 のマネージメントコンソールをシングルページアプリケーションとして作りました。
しかも、Vue + TypeScript に触れて2週間で。というトピックで振り返ってみようと思います。
なぜ Vue + TypeScript にいたったか
GS2 Classic のマネージメントコンソールは Google App Engine を使用していました。
弊社はフルサーバレスアーキテクチャでサービスを作ることに並々ならぬ努力を重ねてきました。
そのため、マネージメントコンソールを作るにあたっても採用できる技術は非常に限られています。
GS2 Classic を GAE で運用してみて感じた一番のツラミはコールドスタート時の スピンアップ速度 でした。
GS2 も GS2 Classic も Function as a Service(いわゆる AWS Lambda) を計算基盤として開発しています。
こちらもスピンアップ速度は課題にはなるのですが、弊社では AWS SDK を OSS で提供されているものではなくよりフットプリントが小さく、高速に動作するものを用意して使用するなど、サービスのレスポンスタイムを短くする努力をしてきました。
一方で、そこまで大量にアクセスが来るわけではないマネージメントコンソールは開発リソースをあまり割けていないのと、アクセス数がサービスのエンドポイントより圧倒的に少ない。というダブルパンチでコールドスタート時の応答速度がストレスを感じるレベルになっていました。
やはり、開発効率重視で Web Application Framework(WAF) を使ったアプリケーションを GAE に乗せてしまったのは大きな過ちだったのだと思います。
コンテナの起動速度だけでなく、ランタイムに使用しているJava仮想マシン(GS2 Classic はサービスでは Python を使用していますが、マネージメントコンソールは Java(Kotlin) で作っています)。そして、WAFの起動とレスポンスタイムを遅くする要素が満載です。
FaaS でも WAF を使った開発をしようというアプローチもありますが、スピンアップ速度が遅くなるので私はおすすめしません。
GS2 Classic も GS2 も非常に薄いレイヤーで設計されており、スピンアップ速度も最小になるよう心がけています。
というわけで、GS2 のマネージメントコンソールを開発するにあたっては割と早期に
『HTML + JS でサービスと同じ REST API エンドポイントを使って提供する』ということを決めていました。
なぜ Vue なのか
React や Angular といった WAF もあります。その中で Vue を選んだ最大の理由は、学習コストが低そうだったことです。
そう、タイトルにもあるように開発にかけられる時間が非常に限られていたのです。
なぜ TypeScript なのか
単に型が厳密な言語が好みだからです。
開発期間は2週間なのはわかったけど、人数は?
基本的に1人。
しかも大量に他の仕事も兼務してる。実質5営業日くらいしかかけられない。
で、できたものは?

Bootstrap 臭いUIなのは気にしないで

Vue コンポーネントを活用して複雑なUIもパズルのように組み合わせて実現してます

いたって普通の入力フォームはこんな感じ

ビューによってはこんなとんでもない入れ子構造のデータもあるけど、Vueコンポーネントならなんとかなった

当然、入れ子構造は入力側でも…
ページ数・コンポーネント数は?
正確に数えてないけど、1マイクロサービスあたりページ数で10。
ビュー用のパネルや入力用のパネルのコンポーネント数で50〜80くらいあると思う。
そのマイクロサービスが30個くらいあります。ひいふうみい…。おう…。
物理的に無理じゃない?
感のいいひとは気づいてしまったでしょう。2週間で 1500〜2000 のコンポーネントを実装するとか無理ゲーだということに。
GS2 はマイクロサービスを DDL で定義していて、そこから色々なものを自動生成しています。
FaaS で動くサービスの雛形とか、サービスにアクセスするための各プログラミング言語向けのSDKとか。
TypeScript でアクセスするための SDK もそうやって作ってます。
@data_structure( parent=Namespace.Namespace, data_owner=DataOwner( owner_holder=DataOwner.OwnerHolderSelf, owner_type=GamePlayer(), ), primary_key=String('accountId'), alternate_keys=[ AlternateKey( field_name='userId', ), ], description=''' ゲームプレイヤーアカウント Account はゲームプレイヤーを特定するためのユーザIDとパスワードを記録します。 ''', ) class Account(BaseModel): accountId = GenericGrn( primary_key=True, require=True, updatable=False, ) userId = UUID( description='アカウントID', require=True, primary_key=True, ) password = String( description='パスワード', require=True, updatable=True, default=Default.Value(), ) createdAt = CreateTimestamp()
モデルの定義はこんな感じ。
@result( items=Array(Account), nextPageToken=String( description='リストの続きを取得するためのページトークン', ), ) class Describe(BaseDescribeAction): namespaceId = Namespace.Namespace.namespaceId pageToken = PageToken() limit = database.AccountDefaultLimit() @path(GET, '/{namespaceName}/account') @policy('DescribeAccounts') @description( ''' {model_name}の一覧を取得 ''' ) @request( (namespaceId, [Request.Default()]), (pageToken, [Request.Default()]), (limit, [Request.Default()]), ) def describeAccounts(self): pass
メソッドの定義はこんな感じ。
で、マネージメントコンソールようにこんな DDL を作った。
@description('{model_name}の新規作成') @path(GET, '/namespace/:namespaceName/account/:userId/take_over/create') class CreatePage(BaseConsolePage): def __init__(self): super().__init__( parent=Account.Console.DetailPage, name='create_take_over', panels=[ Console.Panel.CreatePanel, ], ) class CreateInputPanel(BaseGeneralInputPanel): def __init__(self): super().__init__( properties=TakeOver.Create.createTakeOver.request, ) class CreatePanel(BaseCreatePanel): def __init__(self): super().__init__( method=TakeOver.Create.createTakeOver, input_panel=Console.Panel.CreateInputPanel, )
CreatePage はどういうページを作るかを定義してあって、
CreateInputPanel はどういうフィールドの入力フォームを用意するかが定義してあって、
CreatePanel は入力パネルとその送信先メソッドを定義している。
CreateInputPanel と CreatePanel が分離しているのは CreateInputPanel を入れ子構造の入力フォームで再利用できるように Submit ボタンの挙動を分離している。
というわけで、すべてのモデルデータに対応するDDL宣言を追加していって ジェネレータで一気に Vue コンポーネント を生成するようにした。
つらかったこと
これだけページやパネルがあるとビルド時に node のメモリが不足してなかなか動かなかった。
結局、最終的に32GB割り当ててビルドすることになった。
GS2 ではメモリ 64GB のマシンをみんなに割り当ててるのでよかったけど、みんなどうしてるんだろう。
【登壇資料】Cloud2.0時代のゲーム開発を支えるGS2 / 協業のお知らせ #gc_cloud
みなさんこんにちは。GS2の丹羽です。
本日開催された Google Cloud INSIDE 7 の登壇資料を公開しましたので、お知らせします。
本登壇の中で 第二世代GS2 の発表をさせていただきました。
第二世代のGS2 は現行世代の GS2 では利用料金が時間あたりの利用料金とAPIリクエストあたりの料金の二軸でしたが、完全リクエスト単価制に変更します。
この変更によって、あらゆる規模のゲームにフェアプライシングでサービスを提供できるようになると確信しています。
さらに、Googleの協力の下第二世代GS2の負荷テストを実施したことも報告させていただきました。
第二世代のGS2は現行世代よりも多くのマイクロサービスを実装した状態でこの夏にβテストを開始し、年内にグローバルで正式サービスを開始します。
マイクロサービスを組み合わせることで、パズドラ・モンストのようなゲームをサーバ開発・運用をすることなく提供できるようになります。
本日よりエントリーを受け付けていますので、GS2のサイトより申し込みください。
第二世代のGS2は現時点で秒間10万リクエストをさばけることを確認しており、
この数値はローンチ時にSNSで話題となり、AppStoreやGooglePlayでセールスランク1位となったスクウェア・エニックスさんのシノアリスの秒間アクセス数5.5万を遥かに上回る数値です。
正式サービス開始までにより高い数値を出せるようチューニングを続けてまいります。
あわせて、本日 クラウドエース株式会社 との協業についても報告できることとなりました。
クラウドエースは GCP のプレミアムパートナー で確かな技術を持った会社です。
GS2 は クラウドエース と戦略的業務提携をおこない、公式のGS2リセラーに認定いたしました。
クラウドエースを経由してGS2を利用する場合、GS2を直接契約して利用するよりも細やかなサポートが受けられます。
ぜひともこのパートナーシップを活用して、面白いゲームを夜に送り出していただければと思います。
それでは、また。
【設立2周年】新しい事務所のご紹介と人材募集のお知らせ
みなさん、こんにちは。GS2の丹羽です。
2年前の9月7日に Game Server Services 株式会社 は フルサーバレスアーキテクチャで設計開発された安定したゲームサーバをゲーム開発者の皆様に提供し
ゲームサーバの開発・運用業務から解放し、ゲームを面白くすることに集中出来る環境を提供することをミッションとし、ゲームサーバにおけるUnityたる存在になるべく設立し、無事設立2周年を迎えることが出来ました。
設立当初は本当にサービスを使用してもらえるのか不安だったこともありましたが、採用事例も出てきはじめました。
また、多くの会社様に声をかけていただき、開発の進んでいるタイトルも複数存在するというありがたい状況になりました。
特に今年3月末には多くの皆様のご助力により、無事資金調達を終え新しい仲間を迎えられる資金と、以前から支えてくれているワンダープラネットに加え、DeNA / KLab / GameWith / 大和企業投資 という心強いパートナーを得ることが出来ました。
新しいパートナーの存在によって、より安心してサービスをご利用いただける環境が整い、大企業から声をかけていただく機会も増えました。
まだまだ GS2は開発途上であり、今後も精力的に開発を行いサービスを魅力的なものにしていきます。
新しい事務所のご紹介
新しいメンバーを受け入れる体制を整えるべく、先月末に事務所の改装がおわりましたので、本日は新しい事務所のご紹介から入らせていただきます。
エントランス
エントランスホールのような贅沢な空間はありませんが、玄関ドアを抜けるとコーポレートロゴのあしらわれた壁が出迎えてくれます。
AWS さんからオフィス開設祝いのお花をいただいています。
設立間もないスタートアップですが、いろいろ良くしていただいており助かっています。
執務スペース
広々とした執務スペースはオシャレに飾りました。
1600mm × 1600mm という広いL字デスクを各人に割り当てており、椅子もお好みにあわせて購入しています。
ちなみに、私はハーマンミラーのエンボディチェアを愛用しており、既に本社勤務としてフルタイムで入社してくれている従業員も同じくハーマンミラーのアーロンチェアを使用しています。
今年の AWS Summit 2018 で Startup Architecture of the Year で オーディエンス賞 を受賞していただいたトロフィー & AWS IoT Enterprise Button と、CEDEC 2018 に登壇した際にいただいたチビトロフィーも飾っています。
共有スペース
狭いながらも会議室も用意しています。
会議室とは別に共有部にも 幅2400mm という巨大なホワイトボードを設置しています。
設計の相談をする際に活用しています。
キッチンスペースにはネスプレッソと紅茶のフリードリンクと小腹が空いた時用にお菓子を用意しています。
疲れてきたらお菓子とコーヒーで一服してリフレッシュします。
まだ用意出来ていませんが、近々部屋の奥に仮眠空間を用意する予定があります。
眠い状態で作業を続けてもいいことはありません。
であれば、30分でも1時間でも仮眠を取ってリフレッシュしてから仕事を再開した方が総合的には生産性は高くなると考えています。
仮眠空間にはハンモックやコットを設置してゆっくりできるようにする予定です。
パソコン
ぼかしだらけで失礼します。
全員に iMac 27インチの i7 モデルに64GBのメモリを割り当てたモデルと Ultra Fine 5K ディスプレイを割り当てています。
広大な画面には2枚のIDEとブラウザ、SlackやAsanaといったコラボレーションツールを並べられるスペースがあります。
GS2 ではSDKの開発で様々な言語向けのプログラムを開発したり、各種ゲームエンジン向けにもSDKを開発する必要があるため広い画面と、巨大なメモリが活躍します。

実際にこちらが私のメモリの使用率です。
64GBのメモリが無ければスワップして作業にならないところです。
作業スペースにイヤホンが見えますが、GS2では仕事中に音楽を聴きながら仕事をしても大丈夫です。
ただし、肩を叩かれたりSlackで声をかけられたりしたときには速やかにコミュニケーションがとれる体勢に切り替えて貰う必要はあります。
ちょうど iMac の向こう側には Game Server Services が提供するサービスの稼働状態を表示するディスプレイがあります。
レスポンスタイムやエラーレートが上がるとすぐに検出出来る状態になっています。
人材募集のお知らせ
GS2 では 様々な仕様を持つゲームに対応出来るゲームサーバをフルサーバレスアーキテクチャで設計する という高度なミッションを掲げており、このミッションを成し遂げられる人材を募集しています。
ジョブデスクリプションや諸条件は下記の募集要項ページを参照いただきたいですが、ざっくりと 裁量労働制 年収792万円(月額66万円・みなし残業20時間込み・賞与無し)+ ストックオプション という条件で、サービス開発エンジニアとソリューションアーキテクト兼セールスを募集しています。
要求スキルの高さやミッションの困難さは私も自覚するところですが、スタートアップらしい柔軟な考えでエンジニアが働きやすい職場作りを心がけていますので、我こそは。という方は是非応募してみてください。
それでは、また。
【サービス拡張】GS2-Gold のエンハンス
みなさん、こんにちは。GS2の丹羽です。
今日は GS2-Gold についてお知らせします。
マスターデータ管理がJSONに対応
GS2-Gold は最近では基本的な設計として利用しているJSONによるマスターデータ管理に対応していませんでした。
本日 GS2-Gold はJSONによるマスターデータ管理に対応し、
開発環境と製品環境でマスターデータをやりとりする手間が少なくなりました。
現在 GS2-Gold を利用されている皆様のデータは自動的にJSON形式でのマスターデータ管理にマイグレーションされています。
1つのリソースで複数のゲーム内通貨を扱えるように
これまで GS2-Gold は1つのリソースで1つのゲーム内通貨しか扱えませんでした。
そのため、ゲーム内で複数種類の通貨を扱おうとすると複数のリソースを作成する必要があり、
GS2-Gold はサービスクラス型の課金形態のため、リソース配分の最適化を行うのが難しい。という課題がありました。
今回、1つのリソースで複数のゲーム内通貨を扱えるようになったことで、より低コストで複数のゲーム内通貨を実装いただけるようになりました。
それでは、また。
【サービス拡張】GS2-ConsumableItem のエンハンス
みなさん、こんにちは。GS2の丹羽です。
今日は GS2-ConsumableItem についてお知らせします。
マスターデータ管理がJSONに対応
GS2-ConsumableItem はリリースから1年以上が経過しており、
最近では基本的な設計として利用しているJSONによるマスターデータ管理に対応していませんでした。
本日 GS2-ConsumableItem はJSONによるマスターデータ管理に対応し、
開発環境と製品環境でマスターデータをやりとりする手間が少なくなりました。
現在 GS2-ConsumableItem を利用されている皆様のデータは自動的にJSON形式でのマスターデータ管理にマイグレーションされています。
有効期限付の消費型アイテムに対応
これまで GS2-ConsumableItem の消費型アイテムは有効期限を設定出来ませんでした。
今回のアップデートで消費型アイテムに有効期限が設定出来るようになり、今日限定スタミナ回復アイテム や 今月限定ガチャチケット のようなアイテムを用意出来るようになりました。
ご利用中の消費型アイテムに関しては、有効期限無しの状態で設定し反映しています。
また、この変更に伴っていくつかクォーターの消費量に関して注意事項があります。
DescribeInventory で取得する際に同一アイテムが複数返る可能性があるように
1つのアイテムでも有効期限が異なるアイテムを持てるようになります。
その結果、DescribeInventory で取得する際に同一アイテムが複数返ることがあり得るようになります。
GetInventory でインベントリを取得する際に expireAtの指定が必要に
クォーターの消費量がわかりにくくなるため、おすすめはしませんが expireAt 自体は必須ではありません。
指定しない場合全ての有効期限のアイテムがマージされた数量が応答されるようになります。なお、その際マージ前のインベントリの数分クォーターを消費します。
ConsumeItem で消費するアイテムの種類だけでなく、どの expireAt のインベントリから消費するかを指定できるように
こちらも指定は必須ではありませんが、指定することで特定の有効期限のアイテムを消費出来ます。
ユーザに明示的に有効期限が異なる同一アイテムを並べて、ユーザの意思で消費するアイテムを選択して貰うUIを提供する場合は指定して使うことになります。
逆に、指定しない場合はどうなるか。というと、有効期限に近いアイテムから消費数量を満たせるだけ複数のインベントリからアイテムを消費します。
その際消費したインベントリの数分クォーターを消費します。
所持数量の上限は有効期限毎に効果を発揮する
わかりにくくて申し訳ありませんが、スケーラビリティ確保のために仕方が無かったとご理解いただきたいのですが
GS2-ConsumableItem はアイテム毎に所持数量の上限を設定出来ます。
しかし、有効期限毎にアイテムを別に管理する仕組みにした関係で、このアイテムの所持数量制限は有効期限が異なれば別の所持数量としてカウントされます。
今後もGS2は既存サービスも含めて機能拡張を続けて参ります。
それでは、また。












