ドラゴンクエストXを支える技術 大規模オンラインRPGの舞台裏


ドラゴンクエストXを支える技術 ── 大規模オンラインRPGの舞台裏 (WEB+DB PRESSプラスシリーズ)


技術評論社


著者:青山公士


はじめに
謝辞
目次

第1章 ドラゴンクエストXとは何か-ドラゴンクエストかオンラインゲームか
1.1vドラゴンクエストのオンラインゲーム化
1.2vドラゴンクエストX=オンライン版ドラゴンクエスト
 ドラゴンクエストシリーズ
  RPG-ロールプレイングゲーム
  『ドラゴンクエストIII そして伝説へ…』が社会現象に
  誰にでもクリアできるという衝撃
 オンラインゲーム
  MMORPG-大規模多人数参加型オンラインRPG
  日本にMMORPGを広めた『ファイナルファンタジーXI』
 ドラゴンクエストなのかオンラインゲームなのか
  その芯はドラゴンクエスト
  ドラゴンクエストらしいUI
  「サポート仲間」により1人でも4人プレイ可能に
  「ストーリーリーダー」によりマイペースでプレイ可能に
 Column オンラインゲームと新宿
1.3 ドラゴンクエストXの歴史
 開発の準備
  プロトタイプとイメージデモ動画の作成
  基本ルールの決定
  サーバリソース規模の決定
  ゲームエンジンの決定
 開発
  マイルストーン単位の作業
  リソースデータ,コンテンツの大量生産
  ベータテスト版マスタアップ作業
 ベータテスト
 正式サービスの準備
 Column ベータテスト秘話
  負荷検証
  製品版マスタアップ作業
 正式サービス
  バージョン1『目覚めし五つの種族』
  バージョン2『眠れる勇者と導きの盟友』
  バージョン3『いにしえの竜の伝承』
  バージョン4『5000年の旅路 遥かなる故郷へ』
 海外版サービス
 Column 海外版対応の成功と失敗
1.4 まとめ

第2章 開発・運営体制-ドラゴンクエストXを支える人々
2.1 さまざまな人に支えられるドラゴンクエストX
2.2 ドラゴンクエストX専属の開発コアチーム
 ゼネラルディレクター-堀井雄二さんの存在
 プロデューサー-総責任者
 プロジェクトマネージャー-予算やスケジュールの管理者
 ディレクター-ゲーム内容の責任者
 シナリオ-シナリオドリブン開発の象徴
 Column 絶対的な責任者がいると風通しが良くなる?
 プランナー-細かな設定まで行う各種コンテンツ担当者
 デザイナー-そのゲームに最適化したデータを作る絵師
 プログラマー-仕様調整からコーディングまで行う技術者
 Column 事件はメールで起きているんじゃない。現場で起きてるんだ!
 Webサービス開発-ゲーム連動サービスの実現
2.3 ゲームタイトル横断の開発関連組織
 サウンド-専門設備で作る音の数々
 ムービー-プリレンダリングで作る映像
 研究開発-将来のための研究と現在のための支援
 品質管理-さまざまな視点でのテストプレイ
2.4 オンラインサービス関連組織
 インフラ-オンラインサービスを支える基盤
 顧客管理-アカウント認証と課金
 運営-お客さまへ発信する専門部署
 サポート-お客さまを支援する専門部署
 宣伝-発売日だけではない継続的な露出
2.5 ユーザーからお客さま,そして冒険者へ
2.6 まとめ

第3章 アーキテクチャ-クロスプラットフォームMMORPGの基本構成
3.1 ドラゴンクエストXの構成要素は多岐にわたる
3.2 コンピュータの構成要素-ゲームを動作させるハードウェア
 CPU-命令を実行する装置
 メモリ-記憶領域
 ストレージ-保存領域
3.3 ゲームの構成要素
 インプット-プレイヤー操作
  操作機器の操作
  メニューの選択
 ロジック-ゲームの挙動
  RPGを構成するロジック
  オンラインゲーム特有のロジック
 アウトプット-ゲームの表現
  グラフィックス描画
  サウンド再生
3.4 ゲームアーキテクチャ-基本構成
 ゲームクライアント-見た目上のゲーム本体
 ゲームサーバ-真のゲーム本体
 ゲームDB-主要な情報の保存場所
 クラウドクライアント-操作情報を送信し動画を再生
 クラウドサーバ-動作しているのはゲームクライアント
3.5 プログラミング言語-CPUに与える命令を記述する言語
 プログラミング言語の基本
  CPUネイティブコードと1対1で対応するアセンブリ言語
  より扱いやすいプログラミング言語
 C++-処理負荷の高い部分の実装
  CPUネイティブコードで動くオブジェクト指向言語
 Column プログラマークイズ
  プラットフォームごとに異なるC++ビルド環境
 Lua-試行錯誤したい部分の実装
  実行時に低負荷で,構造的に記述しやすいスクリプト言語
  仮想マシン上のプログラムとして動作
  プログラマーだけでなくプランナーも担当
 C#-開発スタッフ向けGUIツールの実装
  GUIツール開発に適した開発環境
  C++プログラマーが書きやすいプログラミング言語
  C++とC#のツール実装の分担
 そのほかのプログラミング言語-適材適所
 Column 障害調査に便利なツール
3.6 プロトコル-通信方式
 Vce-オンラインゲーム用プロトコル
  RPC形式-プロトコルを意識せずにコーディング可能
  ステートフル-状態を保持した継続通信
  通信内容の保証-順番どおり確実な送受信
  低遅延-レスポンス重視
 Column インターネットは不具合だらけ
 安定した通信環境が必要-MMORPGで要求される通信環境の厳しさ
3.7 リソースデータ-ゲームに必要な各種データ
 グラフィックリソース-ゲーム画面の絵素材
 ムービーデータ-ストリーミング動画データ
 サウンドリソース-BGMとSEのデータ
 テキストデータ-セリフや名称のデータ
 パラメータデータ-多岐にわたる変更が可能なデータ
3.8 まとめ

第4章 開発と検証-並走する追加と保守のサイクル
4.1 ドラゴンクエストXに求められる追加と保守の並走
4.2 開発と検証のサイクル
 新規コンテンツ追加の流れ
  仕様概要の作成-実装の開始を可能に
  新規3DBGの制作開始-最も時間がかかる舞台制作
  仕様の作成-プレイヤー視点の遊び方
  実装-開発作業の中心
  プレイ会の実施-開発スタッフによるテストプレイ
  仕様FIX-残りの改修項目の洗い出し
  改修項目の実装-ディレクターの要望への対応も
  検証-品質管理チームによるテストプレイ
 リリースの流れ
  リリース版の完成
  製品サービス環境へのリリース
 既存コンテンツ保守の流れ
  改修仕様FIX-フィードバックに基づく改修項目の決定
  改修項目の実装-暫定修正を行う場合も
  改修の影響範囲の検証-影響範囲に限定したテストプレイ
4.3 追加と保守の並走体制
 追加と保守は同じチーム
 バージョン番号から見る追加と保守
  1つ目の数値-追加パッケージのバージョン
  2つ目の数値-新規コンテンツ追加のメジャーバージョン
  3つ目の数値-既存コンテンツ保守のマイナーバージョン
  アルファベット-既存コンテンツの緊急修正
 並走バージョン管理
  追加用のTrunkと保守用のMasterの並走
 Column バージョン管理ツールあれこれ
  普段の開発はTrunkで管理
  リリースはMasterで管理
 修正ポリシーの違い
  Trunkの修正は根本,Masterの修正は暫定
  Masterの修正はテクニカルディレクターを通す
 改修ミスの自動検知
  不審な変更検知メール
  ネタバレワード検知メール
 Column メール送信後もフットワークは軽く,粘り強く
4.4 多数並走する検証環境
 検証環境の切り替え-DNSを利用
 社内環境-LANに構築された開発用
  社内個別プログラマー環境-共通システム担当プログラマー用
  社内プログラマー環境-プログラマー用
  社内先行検証環境-品質管理チームによる更新可否の判断用
  社内安定環境-リソースデータ制作を担当する開発スタッフ用
  社内Master環境-Masterの社内検証用
 非公開環境-WANに構築された本検証用
  非公開Trunk環境-次メジャーバージョンの検証用
  非公開Master環境-製品サービス環境の検証用
4.5 まとめ

第5章 メモリ管理-MMORPGのボトルネック
5.1 重要度の高いドラゴンクエストXのメモリ管理
5.2 ゲームクライアントのメモリ管理
 メモリの確保と解放-メモリフラグメントの傾向と対策
  メモリフラグメント問題-メモリの断片化
  コンパクションを伴う間接参照方式-詰めて断片化抑制
  固定長ブロックを利用した直接参照方式-位置固定で断片化抑制
 グラフィックリソース-圧縮状態でインストール
 パラメータデータ-3種類の方法で管理
  常駐パラメータデータ-メモリ内で圧縮保持し都度伸張
 Column メモリ不足でメモリ空く
  都度読みパラメータデータ-必要な場面でメモリに読み込み
  キャッシュ対応パラメータデータ-ファイルの一部をメモリにキャッシュ
 プログラムオーバーレイ-プログラムの入れ替え
5.3 ゲームサーバのメモリ管理
 4Gバイト制限-32ビットアプリケーションの限界
 スワップアウト抑制-サーバマシン搭載のメモリ容量が上限
5.4 Luaのメモリ管理
 場所や機能ごとにファイルを細分化
 ガベージコレクションを意識したコーディング
5.5 まとめ

第6章 ゲームクライアントグラフィックス-魅力的な絵を描画する工夫
6.1 クロスプラットフォームのゲームクライアントグラフィックス
6.2 ゲームが動いて見えるしくみ
 フレーム-ゲーム画面の静止画1枚1枚
 30~60FPS-動いているように見えるフレームレート
6.3 3Dゲームのしくみ
 透視変換-3Dゲーム空間を2Dゲーム画面へ投影
 ライティング-光源の影響の反映
 影-光が届かない場所の判定
6.4 ゲームエンジン-ゲーム開発の基本機能の提供
 マルチプラットフォーム対応-各ハードウェアの機能の有効活用
 各種ツールの提供-整備されたリソースデータ制作環境
 Crystal Tools-内製ゲームエンジン
6.5 キャラクター-手描きアニメ風の表現と着替えによる多様化
 トゥーンレンダリングによる手描きアニメ風の表現
  手描き風の色塗り
  輪郭の描画
 着替えによる多様化
  部位の見た目の変更-装備に対応したポリゴンモデルの差し替え
  部位間の接続-隣接箇所の表示/非表示の切り替え
  カラーリング-色の変更
 キャラクターモーションによる多彩な動作
  キャラクターには骨がある
  関節が外せるキャラクターモーションで多彩な表現
  パート分けと分岐で多様な表現
  物理骨による動的制御で揺れを表現
  フェイシャルアニメーションによる表情変化
 キャラクター制作の流れ
  キャラクターモデル制作の流れ
 Column 制作されし十四の種族
  キャラクターモーション制作の流れ
  フェイシャルアニメーション制作の流れ
 Column モーションキャプチャ活用で求められる演技力
6.6 3DBG-冒険の舞台となる広大な世界
 高速な非表示範囲の判定が重要
 近付いてから読み込む室内グラフィックリソース
 3DBG制作の流れ
6.7 エフェクト-さまざまな視覚効果
 エフェクトのいろいろ
 エフェクト制作の流れ
6.8 カットシーン-物語に添える彩り
 カットシーンとムービーの違い
 物語は最高のごちそう
 ゲームクライアントで生成されたキャラクターが演技
 カットシーン制作の流れ
6.9 メニュー-わかりやすさの中心的役割
 複数の解像度に対応したメニューレイアウト
 メニュー制作の流れ
6.10 まとめ

第7章 ゲームサーバプロセス-機能ごとに分離して負荷分散
7.1 ドラゴンクエストXのゲームサーバプロセスはシングルスレッド
7.2 シングルスレッド-1プロセス1スレッド
 シングルスレッドのメリット-不具合対応しやすい
 シングルスレッドのデメリット-開発と負荷分散がしづらい
  複雑なノンブロッキング形式での開発が必要
  1プロセス1CPUのため負荷分散しづらい
 シングルスレッドのデメリットを補う
  Luaでブロッキング
  マルチプロセスで負荷分散
7.3 ワールドプロセス-スケールアウトのためのパラレルワールド
7.4 ゾーンプロセス-MMORPGの主役
 世界を多数のゾーンに分割
 ワールドプロセスとゾーンプロセスの連携
 ゾーンプロセスは高負荷
7.5 バトルプロセス-ゾーンプロセスから分離した戦闘処理
 戦闘開始-ゾーンプロセスからバトルプロセスへ処理を移管
 戦闘中-バトルプロセスで処理しゾーンプロセスへ共有
 Column AIは賢くないほうが楽しい?
 戦闘終了-バトルプロセスからゾーンプロセスへ処理を戻す
7.6 ロビープロセス-ゲームプレイの起点
7.7 ゲームマスタープロセス-ゲームマスターの指示を中継
7.8 ワールド間の自由移動を支えるプロセスたち
 ワールド間を自由移動できるメリット-ワールドの垣根を越えて一緒にプレイ可能
 ワールドプロセスのマスタとスレーブ-複数のワールドプロセスを接続
 Column プレイヤーイベントあれこれ
 パーティプロセス-ワールドを移動しても分かれないパーティの実現
 メッセージプロセス-ワールド横断コミュニケーションの担い手
 Column 2.27の障害対応30時間
7.9 インスタンスゾーン-同一場所のパラレル化
 パーティプライベート用インスタンスゾーン-自パーティのみの空間
 専用ワールドのインスタンスゾーン-一極集中するコンテンツの舞台を分散
 番号が割り当てられたインスタンスゾーン-丁目やフロアに紐付けて分割
7.10 まとめ

第8章 キャラクター移動-移動干渉による押し合いへの挑戦
8.1 通常移動と移動干渉の両立
8.2 通常移動-ゲームクライアント主体の移動処理
 操作プレイヤーのゲームクライアントで移動
 ゲームサーバで移動
 他プレイヤーのゲームクライアントで移動
8.3 移動干渉-ゲームサーバ主体の移動処理
 直感的な移動干渉のゲーム性
 実現への課題
 移動干渉を実現する挙動
 移動干渉モードへの遷移
 Column 操作主体が他ゲームクライアントの「ドルボード」の相乗り
8.4 移動処理の負荷軽減-多人数の影響を軽減する工夫
 1,000人が動く世界は高負荷/li>
 ゲームクライアントへの情報送信の最適化
  空間分割-空間を分けて対象を限定
  表示中キャラクターリスト-情報が必要なゲームクライアントに限定
 Column 既存のしくみを利用して低負荷にできた「すれちがい」
8.5 場所に紐付く処理-指定場所への移動検知で処理実行
 ゾーンの出口から次のゾーンの入口へ移動
 目的地に到達するとストーリーイベントが進行
8.6 まとめ

第9章 ゲームDB-ワールド間の自由移動を実現する一元管理
9.1 ボトルネックはプレイヤーキャラクターデータの一元管理
9.2 ゲームDBの内部構成
 Oracle Exadata-単体でも高性能なRDBMS
 Kyoto Tycoon-スケールアウト可能なKVS
 ゲームDB中継プロセス-プロトコルの差異を吸収
9.3 プレイヤーキャラクターデータの保存
 同期が不要なところは障害時の巻き戻りを許容
  宝箱-同期が不要なアイテム取得
  レベルアップ-同期が不要なパラメータ変化
 同期が不要なときの保存はKVSでスケールアウト
  プレイヤーキャラクターデータキャッシュ-Oracle Exadataへの保存頻度の低減
  拡張プレイヤーキャラクターデータ-Oracle Exadataに保存しないという選択
 同期が必要なところはトランザクション処理
  「とりひき」-プレイヤーキャラクターデータの同期
  「旅人バザー」-共有データとプレイヤーキャラクターデータの同期
  「住宅村」-ゾーンプロセス固有データとプレイヤーキャラクターデータの同期
9.4 テーブル情報の概説
 アイテム情報テーブル
  ID-アイテムスロットを識別する番号
  アイテム番号-種別を表す番号
  所持数-同一アイテムスロットに所持している数
  所持キャラクター-所持者を表す番号
  保管場所番号-ゲーム上で所持する場所の種類
  更新日時-最後に変更された日時
  状態-アイテムの削除はレコードの削除ではなく状態変更で処理
  追加効果-アイテムに個別に付加する情報
 所持品ソート情報テーブル
 Column 情報量を大幅に減らした「家具庭具おきば」
  旅人バザー関連テーブル
9.5 継続的な改善
 Oracle Exadataのアップグレード
  投入時に発覚した10万分の2秒という重大な遅延
  アップグレード後も性能が上がらず最適化で成果
 Column シンプルなほうが障害に強い
 機能追加に伴うゲームDBの最適化
  アイテム情報の読み込み最適化
  「旅人バザー」統合のための工夫
 ゾーンプロセスによる保存頻度の抑制
  Column 駅のベンチでメンテナンスの真相
 継続的ボトルネック調査
  Column 別空間の「アスフェルド学園」はゲームDBでも別空間へ
9.6 まとめ

第10章 ゲーム連動サービス-ゲーム内とつなげるための工夫と力技
10.1 「目覚めし冒険者の広場」と「冒険者のおでかけ超便利ツール」-2種類のゲーム連動サービス
10.2 ゲーム連動サービスのアーキテクチャ
 連動サービスクライアント-ゲーム連動サービスのブラウザとアプリケーション
 連動サービスサーバ-ゲーム連動サービスの中心的存在
 連動サービスDB-ゲーム連動サービスデータの保存場所
  MySQL-ゲーム連動サービス専用データの保存
  Cassandra-ゲーム連動サービス用に計算されたゲーム内データの保存
10.3 ゲームの世界との連携
 主要ゲーム情報の利用-Oracle Exadataとの連携
 プレイヤーキャラクターデータキャッシュの活用-Kyoto Tycoonとの連携
 ゲーム外で「職人ギルド依頼」「釣り老師の依頼」「日替わり討伐依頼」-ゾーンプロセスとの連携
 ゲーム外で「どこでもチャット」-メッセージプロセスとの連携
 チャットの着信をプッシュ通知-ノンブロッキング形式での通信で高速化
10.4 ゲームクライアントで撮影した写真の加工と保存
 写真の処理-加工と保存の独立化
 画像加工処理の最適化-オンプレミスからAWSへ移行
 写真の管理-NFSからオブジェクトストレージへ移行
10.5 Webで展開しているコンテンツ
 2D,3Dでのプレイヤーキャラクター-ゲーム連動サービスでもプレイヤーキャラクターを表示
 「大討伐」-Webサイトと連動した運営イベント
 「コロシアム」のランキング-ランキング形式のコンテンツ
 「DQXショップ」-ゲーム内のアイテムを現実のお金で購入
10.6 まとめ

第11章 運営と運用-リリースしてからが本番!
11.1 攻めの運営,守りの運用-お客さま対応に必要な両輪
11.2 製品サービス環境へのリリース-メンテナンスの実施
 Column リリース後のほうが多忙
 メンテナンスの作業内容と日時の確定
 メンテナンスの準備
 メンテナンス作業
  クローズ作業-ログイン制限と強制ログアウト
  停止作業-サーバプロセスの停止
  更新作業-バックアップの取得と各種更新
 Column NFSの同期タイミングはサーバマシンごと
  起動作業-サーバプロセスの起動
  チェック作業-作業漏れと製品サービス環境特有の問題の確認
  オープン作業-ログイン許可
 部分的なメンテナンスの実施
11.3 お客さまからの不具合報告への対応
 サポートスタッフによる1次対応
 開発コアチームによる対応
  デイリーレポート-日々メールでやりとりされる不具合対応
  緊急エスカレーション-緊急連絡先へ電話呼び出し
 迅速に対応するためのサーバログ調査の工夫
  調査を意識したログフォーマット-必要な情報を1行に書き出し,情報位置を固定
  Arm Treasure Data eCDPの導入-大量のサーバログを高速に検索できる外部サービスの利用
 Column サーバログの追加にご用心
 わかりやすさの追求
  NPCが保管する仕様は親切だがわかりづらいため通知を強化
  ゴールド額の表示不具合を修正したら大問題になりさらに改修
11.4 お客さまからの要望への対応
 「提案広場」-お客さまの意見を受け付け回答も
 コミュニティ調査-飛び交う本音の分析
 Column 舌を引っ込めた運営スタッフ
11.5 未来へ向けた分析
 サーバ負荷の定量分析
 施策の効果測定
 分析に基づくゲーム内容の改修
  行動調査から,2番目の町へ到達後の進捗が悪いことが発覚
  ゴールドなどの不足を補うコンテンツの追加
  進めてほしいメインストーリーの惹きを強化
11.6 まとめ

第12章 不正行為との闘い-いたちごっこ覚悟で継続対応
12.1 不正行為への継続した対応
12.2 RMTとの闘い-現実の金品によるゲーム内金品の売買を防ぐ
 RMTの実態-業務でゴールドを稼ぐRMT業者の存在
  不正プレイRMT業者-1人では不可能な長時間プレイ
  不正アクセスRMT業者-日本における違法行為
 RMTへの対処-行為検知と,利用抑制の啓蒙活動
  RMT業者の行動パターン変更に追従-スペシャルタスクフォースによる対処
  利用の抑制-利用者の対処と啓蒙活動
12.3 自動操縦との闘い-人間に不可能な長時間プレイを防ぐ
 自動操縦の実態-RMT業者と一般プレイヤー
 自動操縦への対処-複数の手法で検知して対応
  現地視認-ゲームマスターによる手動対処
  サーバログ調査-スペシャルタスクフォースによる手動対処
  行動パターン検出-プログラムによる検出と自動対処
  通報-お客さまの協力で行う自動隔離
12.4 不具合の不正利用との闘い-不当に利を得る行為を防ぐ
 不具合の不正利用の実態-残存する不具合と,それを狙うプレイヤー
  不具合の不正利用への対処-公平性を保つ対応と事前に発見するしくみ
  困難な対処-意図的かどうかの判断は難しい
  無限増殖の不具合の検出-事前に発見する工夫
12.5 プレイヤー間トラブルとの闘い-人間が集まると生じる問題に対応する
 プレイヤー間トラブルの実態-人間が集まれば問題も
 プレイヤー間トラブルへの対処-報告への対応と発生防止策
  利用規約違反報告への対応-警察のような役割のゲームマスター
  ゲーム仕様の改修で未然に防止-トラブルを起きづらくする工夫
12.6 チートとの闘い-改ざんから世界を守る
 チート行為の実態-回数は少なくても大きな影響
  発覚したチート事例-通常の操作ではあり得ない状況
  カジュアルチーターの攻撃-空いていたセキュリティホール
 チート行為への対処-ゲームサーバで防止し,ゲームクライアントで難読化
  チート行為の実施者の対処とその後-残された深い傷跡
  チート防止方法-ゲームサーバで防ぐことが基本
  ゲームクライアントとプロトコルの難読化-カジュアルチーターも意識した対応
12.7 まとめ

あとがき
索引
著者プロフィール

書籍目次

Posted by shi-n