読者です 読者をやめる 読者になる 読者になる

いつクリはてブロ

いつになったらクリエイティブするの?

マルチプレイヤーゲームの不正をどう防ぐか

Ruby 技術

この記事はDXRuby Advent Calendar 201327日目です。嘘です。

前回の記事で、「通信機能を用いて多人数参加型ゲームを作っても、不正を防止するのが難しい」と書きました。
ただ、方法が無いわけではないので、前回省略した具体的な対策方法を書きたいと思います。

1.なるべくサーバー側で処理をする

クライアント側は不正に書き換えられる可能性がありますが、サーバー側で動かしているスクリプトには基本的に手出しができません。
なので、ゲームの処理は全てサーバー側でやってしまうことである程度不正を防止できます。
クライアントに情報を送信させる必要があるので、そこは書き換えられてしまう可能性は残ります。
なのでこれによって100%不正を防ぐことはできませんが、ユーザーが触れる値を最小限にすることはできます。

2.ルームを作成してそこでプレイする形式にする

ゲームシステムで対策する方法です。
ゲームの参加人数を絞りルーム(部屋)を立ててプレイする形式にすると、明らかに不正を行ったプレイヤーを投票により部屋から追い出したり(kick)、不正行為をできないというプレイヤー間の圧力の発生を期待できます。

3.擬似乱数の再現性を利用して不正をチェックする

19日目、@mieki256さんの記事でも取り上げられていますが、擬似乱数の再現性を利用する方法です。
擬似乱数の再現性というのは、乱数のシードをセットしたら同じ順番で同じ結果が得られることです。
6面ダイスなら同じ順番で同じ出目が出る、トランプの山なら同じ順でカードが出る、ということです。
トランプで言うと、例えば7並べの場合、各プレイヤーが順番にカードを一枚ずつ出していくわけですが、誰がどのカードを出したかをログに取っておけば、ゲームの流れを全て後から追いかけることができます。
ゲーム開始時に各プレイヤーに配られる手札は、乱数によって決定されるので、シード値とログさえあればゲームの様子を最初から最後まで再現できるわけです。
これを利用して、チェック用のスクリプトを用意します。
正式なゲームスクリプトにシード値とログを投入して、ゲームを全て再現できたなら、不正は無かったということになります。
逆にどこかで本来起こるべき結果からズレた場合、そこで不正が行われたと確定させることができます。
MMOのように、継続的で途切れ目の無いゲームだと少し工夫が要りますが、ボードゲームのように1プレイがここからここまでと決まっているタイプのゲームは、1プレイごとにチェック用スクリプトを走らせて不正を検出することができます。

4.スクリプトの難読化

24日目、あおいたくさんの記事にもあるように、実行ファイル形式にしてソースコードを読みにくくするのもひとつの方法です。詳しくはそちらを参照してください;-)


以上に挙げた対策は、ひとつひとつは穴があり完璧ではありませんが、複数組み合わせることでかなりの穴を塞ぐことができます。
それ以上はリスクとリターンの問題です。

Advent Calendarへの参加が良い刺激になったので、私もネットワークを利用したゲームを作ってみようと考えています。
是非皆さんもお試しください。そして是非プレイさせてください。