ターン制カジュアルMMORPGゲームサーバーの開発に携わっています。
ネットワーク、マルチスレッド、タイマー、サーバー間通信、メイン ゲーム ループなどを処理する低レベル エンジン (私たちが作成したものではありません) は C++ で作成されました。高レベルのゲーム ロジックは Python で記述されています。
私の質問は、ゲームのデータ モデルの設計についてです。
最初は、クライアントがログインし、定期的にデータをデータ キャッシュ サーバーにフラッシュするタイマーをスケジュールするときに、プレイヤーのすべてのデータを RAM と共有データ キャッシュ サーバーにロードしようとします。データ キャッシュ サーバーはデータをデータベースに永続化します。
しかし、このアプローチにはいくつかの問題があることがわかりました
1) クエストの進行状況、レベルアップ、アイテムとお金の獲得など、一部のデータはすぐに保存または確認する必要があります。
2) ゲーム ロジックによると、オフライン プレイヤーのデータを照会する必要がある場合があります。
3) 一部のグローバル ゲーム ワールド データは、異なるホストまたは同じホストの異なるプロセスで実行されている可能性のある異なるゲーム インスタンス間で共有する必要があります。これが、ゲーム ロジック サーバーとデータベースの間にデータ キャッシュ サーバーを配置する必要がある主な理由です。
4) プレイヤーはゲーム インスタンスを自由に切り替える必要があります。
以下は、過去に遭遇した困難です。
1) ネットワーク I/O がメインのゲーム ロジック スレッドをブロックしないように、すべてのデータ アクセス操作を非同期にする必要があります。メッセージをデータベースまたはキャッシュ サーバーに送信し、データ応答メッセージをコールバック関数で処理して、ゲーム ロジックを続行する必要があります。db と何度も対話する必要がある適度に複雑なゲーム ロジックを記述するのはすぐに苦痛になり、ゲーム ロジックは多くのコールバック関数に散らばっているため、理解と保守が困難になります。
2) アドホック データ キャッシュ サーバーは物事をより複雑にします。データの一貫性を維持し、データを効果的に更新/読み込み/更新することは困難です。
3) ゲーム内データのクエリは非効率的で面倒です。ゲーム ロジックは、インベントリ、アイテム情報、アバターの状態などの多くの情報をクエリする必要があります。たとえば、1 つのステップが失敗した場合、操作全体をロールバックする必要があるなど、いくつかのトランザクション メカニズムも必要です。 . 私たちは、RAM 内に優れたデータ モデル システムを設計し、多数の情報クエリを容易にするために多くの複雑なインデックスを構築し、トランザクション サポートを追加しようとしています。すぐに、私たちが構築しているのはインメモリ データベース システムであることに気付きました。車輪を再発明しているのです。 ..
最後に、スタックレス python に目を向けます。キャッシュ サーバーを削除しました。すべてのデータはデータベースに保存されます。ゲーム ロジック サーバーはデータベースに直接クエリを実行します。スタックレス python のマイクロ タスクレットとチャネルを使用すると、ゲーム ロジックを同期して記述できます。記述と理解がはるかに簡単になり、生産性が大幅に向上します。
実際、基礎となる DB アクセスも非同期です。1 つのクライアント タスクレットが別の専用 DB I/O ワーカー スレッドにリクエストを発行し、タスクレットがチャネルでブロックされますが、メインのゲーム ロジック全体はブロックされず、他のクライアントのタスクレットがスケジュールされます。そして自由に走る。DBデータが応答すると、ブロックされたタスクレットが起動され、「ブレークポイント」で実行され続けます(継続?)。
上記の設計で、いくつか質問があります。
1) DB アクセスは以前のキャッシュ ソリューションよりも頻繁になります。DB は高頻度のクエリ/更新操作をサポートできますか? 近い将来、redis、memcached などの成熟したキャッシュ ソリューションが必要になりますか?
2) 設計に重大な落とし穴はありますか? 特にゲーム内のデータ管理パターンについて、より良い提案をしていただけませんか。
任意の提案をいただければ幸いです、ありがとう。