MMORPGSの大部分には、X時間ごとにすべてのキャラクターを保存するWorldsaveシステムがあります。理由はパフォーマンスだと思います。では、切断時にキャラクターを保存するよりもパフォーマンスの面で優れているのはなぜですか?
MMORPGSの大部分には、X時間ごとにすべてのキャラクターを保存するWorldsaveシステムがあります。理由はパフォーマンスだと思います。では、切断時にキャラクターを保存するよりもパフォーマンスの面で優れているのはなぜですか?
回答:
これはパフォーマンスのためではありません。これはフェイルセーフです。世界が数分ごとに保存する場合、サーバーに何かが発生してシャットダウンすると、全員が数分しか進行しません。
切断時に保存することにより、サーバーに問題がある場合、ログオン後に行ったすべての作業がすべて失われます。(MMOで一般的であるように)特に長時間のプレイセッションでは、大量のデータが失われます。
大量のデータ損失のリスクを取り除くために、パフォーマンスを少し犠牲にします。
もちろん、プレーヤーデータをクライアントマシンに簡単に保存して、ネットワークトラフィックを削減できます。ここでの問題は、ハッキングに対して開かれていることです。ある人がチートの方法を考え出すと、それを共有し、全員がそれをやっています。
編集:として@Philippが、これはまた、アイテムを複製する機能を削除し、指摘しました。切断時保存システムでは、サーバーがクラッシュする前にトランザクションが行われ、クラッシュする前に1人がログアウトした場合、両方のプレイヤーはアイテムを削除するか複製するかのいずれかで、最後にログアウトした時点にロールバックされます。
切断時にのみ保存される初期のシステムは、プレーヤーがアクティブな間も定期的に保存される傾向がありました。これらのシステム、通常はMUD(マルチユーザーダンジョン)では、キャラクターは定期的にファイルにダンプされるまでメモリに保持されていました。
これは、ユーザーが「キャンプ」せずに切断した場合、通常は最後に保存したときからいくつかの部屋が離れており、略奪品やXPなどの束が失われていることを意味します。その点では、コンソールRPGが今日どのようにプレイするかのように振る舞います(コンソールをオフにせずにゲームを保存するか、最後に保存してからすべてを失う必要があります)。
システムは本来の目的のために機能しました。キャラクターが互いにやり取りできなかったのは、おそらく、メッセージやアイテムを互いに送信できる「メール」システムを経由した場合を除きます。アイテムを失い、進行する可能性はかなり大きくなる傾向がありましたが、ほとんどの場合、一度に1人のキャラクターにしか影響しませんでした。
キャラクターが最終的に相互に直接やり取りできるようになったため、ワールドセーブ機能が実現しました。そのため、プレイしているすべてのキャラクターが一貫した状態でなければなりません。これはMUDシナリオでは問題ではありませんでした。アイテムまたは通貨の重複を招くような方法でシステムを悪用することは困難でしたが、初期のMMO MUDでは非常に簡単に実行できました。プレイヤーAはプレイヤーBにアイテムを与え、プレイヤーBは保存し、プレイヤーAは保存せずに切断します。インスタント複製。
Worldsaveはパフォーマンス上の利点ではありませんが、不正行為を防ぐように設計されています。worldsaveイベントが文字通り事前にアナウンスされたシステムでプレイしたことを思い出し、サーバーがすべてのファイルを更新している間、しばしばシステム全体を1分間ハングさせました。これにより不正行為は防止されましたが、これらのシステムのユーザーにとってはあまり便利ではありませんでした。
それが私たちを現状に導きます。現在、worldsave型の関数は使用していません。データベースを使用します。これにより、複製と削除を可能な限り最小限に抑えることができます。文字はデータベース内のレコードとして存在し、プレイヤー間の各トランザクションはリテラルデータベーストランザクションです。アクションが完全にコミットされるか、ロールバックされます。
システムの異常なバグがなければ、個々のキャラクターファイルを保存するメリット(迅速な保存時間)とワールドセービングのメリット(不正行為なし)が得られますが、どちらの欠点もありません(大きな進歩とアイテムの重複を失います)。
最新のMMOを設計するときは、データベースにストアドプロシージャを作成し、それらのプロシージャを使用してトランザクションを実行します。たとえば、2人のプレイヤー間で取引を行う場合、次のようになります。
start transaction;
insert into inventory (playerid, itemid) values (111, 222);
delete from inventory where playerid=111 and itemid=444;
insert into inventory (playerid, itemid) values (333, 444);
delete from inventory where playerid=333 and itemid=222;
commit;
(注:このSQLは、実用的な方法で作成されたものではなく、単なる例にすぎません)。
このように、コミットの前にクラッシュがあった場合、システムはプレーヤー111とプレーヤー333がまだ元のアイテムを保持している状態にロールバックしますが、コミット後、取引は完了します。データベースで保証されているように、文字は同時に保存されるため、複製の機会はありません。