過去2年間、RedDwarfプラットフォームでゲームサーバーを開発しています。Javaでオンラインゲームを作成するための無料(GPLv2)サーバープラットフォームです。 このプラットフォームに関するHabréの情報はほとんどないため、この欠点を修正することにしました。
物語
このエンジンの開発は当初Sunによって行われ、プラットフォーム自体はSun Game Serverと呼ばれていました(頭字語sgsはパッケージ名にまだ使用されています)。 2005年、サーバーはProject Darkstarという名前で世界に紹介されました。 OracleがSunを買収した後、要人はプロジェクトのサポートを拒否し、プラットフォームはRedDwarf Serverに名前が変更され、現在はコミュニティのサポートによってのみ存在しています。 現在、プロジェクトの開発は非常に遅くなっていますが、まだ開発中です-昨年バージョン0.10.2がリリースされました。 計画されているすべての機能(透過スケーリング)はまだ含まれていませんが、ゲームサーバーの基礎として多くのプロジェクトで使用されています 。
基本原則
RedDwarfプラットフォーム上のゲームサーバーは、次の部分で構成されています。
- ゲームアプリケーション
- 拡張機能
- コア
- 内部DB
内部データベースは、高性能な組み込みデータベース(BerkleyDBで使用)であり、ゲーム中にサービスとゲームのデータを保存するために使用されます。 このデータベースには、すべてのゲームオブジェクト、ゲーム、内部タスク、およびイベントが保存されます。 トランザクションタスクが実装されるのは、データベースの助けを借りてです。 これにより、停止したのと同じ場所から実行できます。ゲームは何も起こらなかったかのように続行します。
RedDwarf カーネルには、ネットワークを使用したBerkleyDBデータベースの操作、ユーザーの接続/切断、スケジュールされたタスクと定期的なタスクのスケジューリングに関するすべての心配が含まれています。
拡張機能は、カーネルに含まれていない機能を簡単に使用できるようにするプラグインです。 プロファイリング、外部データベース(SQL)の操作、およびHTTPサービスの操作のための拡張機能があります。
ゲームアプリケーションは、ゲームの開発者によってJava言語で記述されています。 ゲームアプリケーションは、カーネルと拡張機能によって提供されるAPIを使用します。 RedDwarfはゲームアプリケーションにいくつかの制限を課します。タスクは短く、直接入力/出力ではなく、独自のスレッドを作成せず、タスクメカニズムを使用する必要があります。
タスク
ゲーム(または内部)イベントはすべてタスクです。 タスクはシリアル化され、データベースに書き込まれ、可能な限り読み取られて実行されます。 各タスクの開始時に、内部データベースのトランザクションが開かれ、タスクが完了した後、トランザクションがコミットされます。 タスクの実行中に未処理の例外が発生した場合、またはタスクが100ミリ秒(デフォルト)以上実行された場合、トランザクションはロールバックされます。
これに関して、別の興味深い点:トランザクションの競合がある(つまり、同じゲームオブジェクトが異なるタスクで並行して変更された)場合、トランザクションはロールバックされ、タスクが再度実行されます。 これにより、プログラムはシングルスレッドとして記述されます-同期コレクションとブロックコレクションの使用も禁止されます(デッドロックにつながる可能性があります)。
データベースにタスクを保存すると、独自の機能が提供されます。
1つ目は、サーバーが停止またはクラッシュした後、サーバーを安全に再開する機能です。 確かに、実際には、サーバークラッシュが雪崩のようなタスクの乗算(コードのエラーによる)によって引き起こされた場合がありました。サーバーを復元するには、シャーマンを大量に行うか、データベース全体を削除する必要がありました。
2番目のユニークな機会は、透過的なスケーリングを作成することです。シリアル化されたタスクは、サーバークラスターの個々のノード間で簡単に転送され、可能な場合は実行されます。 残念ながら、このスケーリングはまだ完全に実装されておらず、実際にはまだ適用できません。
プラットフォームには、1回限りの遅延タスクおよび定期タスクを計画し、それらをキャンセルできる便利なシェダーがあります。
JMXを使用して、サーバーのステータスと管理を監視することができます。
管理対象オブジェクト
トランザクション性を確保し、プログラマーが(ほとんど)マルチスレッドについて考えないようにするには、すべてのゲームオブジェクトがManagedObjectインターフェイスを実装する必要があります。 このようなオブジェクトの操作は、トランザクションのフレームワーク内でのみ実行できます(つまり、独自のスレッドを開始して、そのようなオブジェクトを操作することはできません)。 そのようなオブジェクトへのリンクは、明示的に保存するのではなく、特別なオブジェクトManagedReference内に保存する必要があります。 このようなリンクを逆参照する必要は少し面倒ですが、これによりロックの混乱が解消されることを覚えておくと、すぐに慣れます。
大量メッセージ配信チャネル
Reddwarfの下でゲーム開発者に与えられる素晴らしい機会は、メッセージチャネルです。 チャンネルには多数のサブスクライバーを含めることができ、メッセージがチャンネルに公開されると、すべての受信者に配信されます。 チャネルの実装により、このメカニズムは、サイクル内のすべてのサブスクライバーをバイパスして各サブスクライバーにメッセージを送信するよりもはるかに高速に動作します。
クライアント部
RedDwarfには、クライアントパーツをさまざまなプログラミング言語で記述するためのライブラリが多数あります。 プラットフォーム開発者は、 JavaおよびCクライアントライブラリをサポートしています。 ActionScript、Objective-C、C#、Pythonのライブラリもあります。
ゲーム開発者に求められるもの
プラットフォーム自体にはすでに多くの機能が実装されているため、ゲームを入手するにはプログラマーは次のことを行う必要があります。
- ゲームエンティティとそれらの間の関係を作成します。
- ゲームデータのストレージを実装します(組み込みデータベース、または外部データベースの拡張機能を使用して)。
- サーバーとクライアントの通信用のプロトコルを開発します(RedDwarf自体にはこのためのツールはほとんどありません)。
- ゲームロジック、クライアントアクションに対するサーバーの応答をプログラムします。
おわりに
その結果、Reddwarfはオンラインゲームサーバーを開発するための優れたプラットフォームであると言えます。プログラマーをマルチスレッド化の心配から解放し、内部データベース、タスク、およびネットワークで作業するための便利なAPIを提供します。
次の記事では、RedDwarfの下で最初のアプリケーションを作成する方法を書きました 。
文学
プロジェクトの公式サイト
Reddwarfに関するFAQ
建築プレゼンテーション