Amazon GameSparks(プレビュー版)を使ってみた

2022.09.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWSから2022年3月にAmazon GameSparksというゲームサーバーを構築するためのマネージド バックエンドサービスがプレビュー版として公開されました。サービスを使ってみたところ、今後のゲーム開発がより効率よく開発できる可能性があることが見えてきました。そこで、ここで改めて紹介していきます。

特徴

Amazon GameSparksの最大の特徴として、ゲームサーバがマネージドサービスとして運用できる点です。

これまでAWSにてゲームサーバ(ゲームのクライアントからのリクエストを捌くサーバ)を構築する場合、EC2、RDS、Lambdaなどのサービスを利用して構築していたことでしょう。

これらのサービスは汎用的なサービスであるため、ゲームサーバとして活用するために必要な機能を開発者が設計・実装しなければなりませんでした。

GameSparksはゲームサーバのマネージドサービスであり、ゲームのバックエンド開発に必要な機能はすでに考慮済みとなっています。マネージドサービスですのでユーザからのアクセス数に応じたサーバのスケールアップ、スケールダウン、あとはサーバ監視などといったサーバ運用の手間も大幅に削減できます。

あと、Amazon GameSparksはそれ単体でサービスが利用できるよう設計されているため、既存の他AWSサービスをあまり知らなくてもゲームサーバが構築、運用できます。

もちろんDynamoDBなど他AWSサービスとの連係も可能ですので、他AWSサービスについての知識があれば、より幅広い使い方ができるようになるのは言うまでもありません。

機能

プレビュー版で用意されている機能をみていきます。プレビュー版では以下の機能を利用できます。

  • メッセージ&クラウドコード
  • Unityとの連係
  • DynamoDBとの連駅
  • Lambdaとの連係
  • テストハーネス

ここでは、ゲームサーバとクライアントとの通信方法、ゲームサーバの開発手法・デプロイの流れを解説します。上記の項目では「メッセージ&クラウドコード」「Unityとの連係」に該当します。

その他の項目は、What is Amazon GameSparks? - Amazon GameSparksをご覧下さい。

ゲームサーバとクライアントとの通信方法

ゲームサーバを設計する際、早い段階でクライアントとサーバとの通信手法を考えることになるでしょう。このあたりは、HTTPを使った通信を行う、もしくはWebSocketを使って通信を行うのが一般的でしょう。

GameSparksはWebSocketベースで通信を行っています。そして、クライアント・サーバ間での通信手法はGameSparksですでに設計済みです。そのため、ゲーム開発者は通信でやりとりするデータの値やデータ形式(例えば、プレイヤが所持しているゴールドを整数値で送る、といったように)を考慮して、コーディングするだけで済みます。

言い換えると開発者はサーバ・クライアント間の通信手法などを気にすることなく、ただサーバ・クライアント間を行き交うデータのみに注力して開発できます。では、これらの手法でどのように開発が進められていくかは、このあと解説します。

ゲームサーバの機能を実装する

実際にGameSparksを使ってサーバー機能を実装します。GameSparksは現在プレビュー版であり、現在バージニア北部リージョンでのみ利用可能です。正式リリース版では手順や機能が異なる可能性があります。

プロジェクトの生成

GameSparksに対してプロジェクトを作成します。ここではGameSparkSandbox1として作成しました。

ゲームサーバ側のコードを実装

ゲームサーバで動作させる処理(ソースコード)を実装します。ソースコードはAWSマネジメントコンソールから記述できます(AWS CLIを使ってコードを登録することも可能です)。

ここではリクエストパラメータとして受けとった2つの整数値Val1、Val2を加算してResValとして値を返すAddValuesメッセージを作成してみます。

コードは以下のようになります。言語はJavaScriptとなります。

処理内容としては、リクエストパラメータはmessage.Val1、message.Val2とmessage.という形式で受けとることができます。Val1とVal2の値を加算してResValueに返しています。

GameSparks().Logging().Debug("Add 2 values");
let val = message.Val1+message.Val2;
return GameSparks().Messaging().Response( { "ResValue": val } );

ゲームサーバにデプロイする

ソースコードをゲームサーバにデプロイします。Deploy as new snapshotボタンを押すとゲームサーバにデプロイされます。

動作確認する

AddValuesメッセージが正常に動作するか確認してみます。動作確認はTest harnessという機能を利用します。AddValuesメッセージに対してRequest bodyで渡すパラメータを指定し、Send messageボタンを押して実行します。実行結果は、Log inspectorに表示されます。

クライアントの実装

次にクライアント側を実装します。GameSparksでは、サーバ側のリクエストやレスポンスを含むコードを自動生成し、そのコードをクライアント側のプロジェクトに取り込み、コードを参照することで実装できるようになっています。なお、現在のGameSparksでは、Unity&C#のみ対応しています。おそらくUnrealEngineにも対応する予定なのかもしれません。

では、ソースコードを生成していきます。まずSnapshotからGenerateCodeを選択します。すると、ゲームクライアントプラットフォームとプログラミング言語の指定ができますので、UnityとC#を選択し、Generate Codeを押します。

すると先のAddValuesメッセージに必要なパラメータ定義を含んだC#のコードが生成されます(実際にはC#のファイルを含んだZIPファイルをダウンロードします)。

生成されたコードは次の通りとなります。

using System;
using Amazon.GameSparks.Unity.DotNet;
using Amazon.GameSparks.Unity.EngineIntegration;
using Newtonsoft.Json;
 
namespace Amazon.GameSparks.Unity.Generated
{
    public static class GameSparksSandbox1Operations
    {
 
        public sealed class AddValuesRequest
        {
            [JsonProperty]
            public int Val1 { get; }
            [JsonProperty]
            public int Val2 { get; }
 
            public AddValuesRequest(
                int Val1,
                int Val2)
            {
                this.Val1 = Val1;
                this.Val2 = Val2;
            }
 
            public override string ToString()
            {
                return string.Concat(
                   $"{nameof(Val1)}: { Val1 }", Environment.NewLine,
                   $"{nameof(Val2)}: { Val2 }");
            }
        }
 
        public sealed class AddValuesResponse
        {
            [JsonProperty]
            public int ResValue { get; }
 
            public AddValuesResponse(
                int ResValue)
            {
                this.ResValue = ResValue;
            }
 
            public override string ToString()
            {
                return string.Concat(
                   $"{nameof(ResValue)}: { ResValue }");
            }
        }
 
        public static void EnqueueAddValuesRequest(
            this Connection connection,
            AddValuesRequest payload,
            Action<Message<AddValuesResponse>> handleResponse,
            Action<Message<DefaultError>> handleError,
            Action handleTimeout,
            TimeSpan timeout)
        {
            connection.SendRequest(
                new Message<AddValuesRequest>("Custom.Game.AddValues", payload),
                timeout,
                handleResponse,
                handleError,
                handleTimeout);
        }
 
 
    }
}

このC#のソースコードを用意したUnityのプロジェクトに取り込みます。これで、サーバから返されたレスポンスをUnityのソースコードから参照できます。

このソースコードを軽く解説するとAddValuesRequestメソッドはリクエストパラメータを作成するためのメソッド、AddValuesResponseメソッドはレスポンスを格納するメソッド、EnqueueAddValuesRequestメソッドは、クライアント(Unity)からサーバにあるAddvaluesメッセージを呼びだすためのメソッドとなります。

まとめ

このようなサーバ・クライアント間の通信を行う場合はコーディングする以前にAPI仕様書といったさまざまな設計が必要となります。それ以前にネットワーク関連のプログラミングになれてないと、さまざまな学習も必要となるでしょう。

しかし、GameSparksを利用することで、サーバ・クライアント間の通信を意識せずにネットワーク関連の実装ができ、その浮いた時間をゲームに必要な処理などに時間をさくことができるでしょう。

先ほども記載した通りGameSparksはまだプレビュー版ですので、今後もさまざまな機能が実装されることが予想されます。GAとなった場合は、またあらためて取り上げたいと思います。