マルチスレッド ゲーム サーバーはどのように作成されますか?
スレッドが 4 つある場合、ゲーム ループを実行するスレッドが 1 つと、リクエストを受け入れて処理するスレッドが 3 つあるでしょうか? また、ゲーム ループを実行しているスレッドから情報が送信されますか?
マルチスレッド ゲーム サーバーはどのように作成されますか?
スレッドが 4 つある場合、ゲーム ループを実行するスレッドが 1 つと、リクエストを受け入れて処理するスレッドが 3 つあるでしょうか? また、ゲーム ループを実行しているスレッドから情報が送信されますか?
主な鍵は、ゲーム ロジックがスレッド モデルの影響を受けないようにすることです。
そのため、ほとんどのゲーム サーバーは次のようになります。
main() {
gGlobalReadOnlyStuff = LoadReadOnlyStuff();
SpawnThreads(numCores); // could be another limiting resource...
WaitForThreadsToBeReadyToGo();
while(1) {
WaitForNetworkInput(networkInput);
switch(networkInput.msg) {
case ADMIN_THING: // start/stop websever, dump logs, whatever...
DoAdminThing(networkInput.params);
break;
case SPAWN_GAME: // replace 'game' with 'zone' or 'instance' as needed
idThread = ChooseBestThread(); // round robin, random, etc
PostStartGameMessageToThread(idThread, networkInput.msg);
break;
// ...
}
}
}
void ThreadUpdate() {
threadLocalStuff = LoadThreadLocalStuff();
SignalThreadIsReadyToGo();
while(1) {
lock(myThreadsMessageQueue);
// copy messages to keep lock short
localMessageQueue = threadsMessageQueue;
unlock(myThreadsMessageQueue);
foreach(message in localMessageQueue) {
switch(message.msg) {
case SPAWN_GAME:
threadLocalStuff.games.MakeNewGame(message.params));
break;
case ADMIN_THING__LET_EVERYONE_KNOW_ABOUT_SERVER_RESET:
...;
break;
// etc...
}
}
foreach(game in threadLocalStuff.games) {
game.Update(); // game will handle its own network communication
}
}
その場合の 2 つの難しいことは、「ゲームに適したパーティション (ゲーム、ゾーン、インスタンスなど) を考え出すこと」と「それらの境界を越えて物事 (プレイヤー、火の玉、壮大な戦利品) を移行すること」です。データベース」ですが、ソケット/メッセージ/ファイルなどを使用できます。しかし、ええ、これらのパーティションをどこでどのように作成し、境界を越える可能性があるものを最小限に抑えるかは、ゲーム デザインと密接に関係しています。
(そして、はい、セットアップによっては、マルチスレッド処理が必要な「共有」システム (ログ、メモリ) がいくつかある可能性があります (または、スレッドごとに 1 つのロガー/ヒープを使用することをお勧めします))
スターキーは、正確な設計に大きく依存することをすでに指摘しました.
たとえば、多数のクライアントを含むゲームでは、専用のスレッドを入力の処理に割り当てますが、少数のクライアント (たとえば <=16) を含むゲームでは、複数のスレッドは必要ありません。
一部のゲームでは、かなりの頭脳を持つ NPC が登場します。それらを独自のスレッドで実行するのは賢明かもしれませんが、スレッドプールが多すぎる場合は、多数の NPC が 1 つのスレッドを共有できるようにスレッドプールが必要になります。
永続的な世界がある場合は、状態をどこかのハードディスクに (おそらく DB 経由で) 書き出す必要があります。これには重大なレイテンシがあるため、その I/O でメインのゲーム ループを待機させたくないでしょう。それは別のスレッドになります。
最後に、メインのゲーム ループがあるかどうかという問題があります。MMO のループは 1 つですか、それともループが多いですか?